# Build 'service' sub-project
SConscript(build_dir + 'service/SConscript')
-# Build "plugin interface" sub-project
-SConscript(build_dir + 'plugins/SConscript')
-
# Build "cloud" sub-project
SConscript(build_dir + 'cloud/SConscript')
+# Build "plugin interface" sub-project
+SConscript(build_dir + 'plugins/SConscript')
+
# Append targets information to the help information, to see help info, execute command line:
# $ scon [options] -h
env.PrintTargets()
# build android_api
jdk_env = Environment(ENV=os.environ)
-jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + os.getcwd()+'/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED), emitter = ensure_libs)
+jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + os.getcwd()+'/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s -DSECURE=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED, ANDROID_SECURED), emitter = ensure_libs)
jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
cmdBuildApi=jdk_env.Gradle(target="base/objs", source="base/src/main/java/org/iotivity/base/OcResource.java")
-jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + 'android/examples/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED))
+jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + 'android/examples/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s -DSECURE=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED, ANDROID_SECURED))
cmdBuildExamples=jdk_env.Gradle(target="../examples/devicediscoveryclient/apk", source="../examples/devicediscoveryclient/src/main/java/org/iotivity/base/examples/DeviceDiscoveryClient.java")
# android examples require android api to be built before being invoked
minSdkVersion 21\r
targetSdkVersion 21\r
versionCode 1\r
- versionName "1.0"\r
+ versionName "1.1"\r
+ buildConfigField 'int', 'SECURED', SECURED\r
}\r
buildTypes {\r
release {\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/ocsocket/include\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/oc_logger/include\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../extlibs/boost/boost_1_58_0\r
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../extlibs/cjson\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../build_common/android/compatibility\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/provisioning/include\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/provisioning/include/oxm/\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/provisioning/include/internal\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/include\r
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/connectivity/api\r
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/connectivity/lib/libcoap-4.1.1\r
include $(BUILD_SHARED_LIBRARY)\r
delete jniPinListener;
jniPinListener = new JniPinCheckListener(env, jListener);
CBData.loadSecretCB = InputPinCodeCallback;
- CBData.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
+ CBData.createSecureSessionCB = CreateSecureSessionRandomPinCallback;
CBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
CBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
result = OCSecure::setOwnerTransferCallbackData((OicSecOxm_t)OxmType,
try
{
+ if (timeout < 0)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "Timeout value cannot be negative");
+ return nullptr;
+ }
OCStackResult result = OCSecure::discoverUnownedDevices((unsigned short)timeout, list);
if (OC_STACK_OK != result)
try
{
+ if (timeout < 0)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "Timeout value cannot be negative");
+ return nullptr;
+ }
OCStackResult result = OCSecure::discoverOwnedDevices((unsigned short)timeout, list);
if (OC_STACK_OK != result)
{
try
{
+ if (timeout < 0)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "Timeout value cannot be negative");
+ return nullptr;
+ }
OCStackResult result = OCSecure::getDevInfoFromNetwork((unsigned short)timeout,
ownedDevList, unownedDevList);
if (OC_STACK_OK != result)
(JNIEnv *env, jobject thiz, jint timeout, jobject jListener)
{
LOGD("OcSecureResource_removeDevice");
+ if (timeout < 0)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "Timeout value cannot be negative");
+ return;
+ }
+
if (!jListener)
{
ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
jmethodID g_mid_OcOicSecAcl_get_periods_cnt = nullptr;
jmethodID g_mid_OcOicSecAcl_get_periods = nullptr;
jmethodID g_mid_OcOicSecAcl_get_recurrences = nullptr;
-jmethodID g_mid_OcOicSecAcl_get_owners_cnt = nullptr;
-jmethodID g_mid_OcOicSecAcl_get_owners = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_rownerID = nullptr;
jobject getOcException(JNIEnv* env, const char* file, const char* functionName,
const int line, const int code, const char* message)
g_mid_OcOicSecAcl_get_recurrences = env->GetMethodID(g_cls_OcOicSecAcl, "getRecurrences", "(I)Ljava/lang/String;");
if (!g_mid_OcOicSecAcl_get_recurrences) return JNI_ERR;
- g_mid_OcOicSecAcl_get_owners_cnt = env->GetMethodID(g_cls_OcOicSecAcl, "getOwnersCount", "()I");
- if (!g_mid_OcOicSecAcl_get_owners_cnt) return JNI_ERR;
-
- g_mid_OcOicSecAcl_get_owners = env->GetMethodID(g_cls_OcOicSecAcl, "getOwners", "(I)Ljava/lang/String;");
- if (!g_mid_OcOicSecAcl_get_owners) return JNI_ERR;
+ g_mid_OcOicSecAcl_get_rownerID = env->GetMethodID(g_cls_OcOicSecAcl, "getRownerID", "()Ljava/lang/String;");
+ if (!g_mid_OcOicSecAcl_get_rownerID) return JNI_ERR;
return JNI_CURRENT_VERSION;
}
extern jmethodID g_mid_OcOicSecAcl_get_periods_cnt;
extern jmethodID g_mid_OcOicSecAcl_get_periods;
extern jmethodID g_mid_OcOicSecAcl_get_recurrences;
-extern jmethodID g_mid_OcOicSecAcl_get_owners_cnt;
-extern jmethodID g_mid_OcOicSecAcl_get_owners;
+extern jmethodID g_mid_OcOicSecAcl_get_rownerID;
typedef void(*RemoveListenerCallback)(JNIEnv* env, jobject jListener);
#include "JniSecureUtils.h"
#include "JniOcSecureResource.h"
+#include "srmutility.h"
#include "base64.h"
jobject JniSecureUtils::convertProvisionresultVectorToJavaList(JNIEnv *env, const OC::PMResultList_t *result)
return deviceId.str();
}
-void JniSecureUtils::convertStrToUUID(char *str, OicUuid_t &uuid)
-{
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
-
- b64Ret = b64Decode(str, strlen(str), base64Buff, sizeof(base64Buff), &outLen);
- memcpy(uuid.id, base64Buff, outLen);
-}
-
jobject JniSecureUtils::convertUUIDVectorToJavaStrList(JNIEnv *env, UuidList_t &vector)
{
jobject jList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);
}
char *str = (char*) env->GetStringUTFChars(jData, 0);
- convertStrToUUID(str, acl->subject);
- env->ReleaseStringUTFChars(jData, str);
+ if (OC_STACK_OK == ConvertStrToUuid(str, &acl->subject))
+ {
+ env->ReleaseStringUTFChars(jData, str);
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
jint jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecAcl_get_resources_cnt);
if (!jCount || env->ExceptionCheck())
acl->recurrences[i] = (char*) env->GetStringUTFChars(jData, 0);
}
- jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecAcl_get_owners_cnt);
- if (!jCount || env->ExceptionCheck())
+ jData = (jstring) env->CallObjectMethod(in, g_mid_OcOicSecAcl_get_rownerID);
+ if (!jData || env->ExceptionCheck())
{
return OC_STACK_ERROR;
}
- acl->ownersLen = jCount;
- acl->owners = new OicUuid_t[acl->ownersLen];
- if (!acl->owners)
- {
- return OC_STACK_ERROR;
- }
+ str = (char*) env->GetStringUTFChars(jData, 0);
- for (jint i = 0; i < jCount; ++i)
+ if (OC_STACK_OK == ConvertStrToUuid(str, &acl->rownerID))
{
- args[0].i = i;
- jData = (jstring) env->CallObjectMethodA(in, g_mid_OcOicSecAcl_get_owners, args);
- if (!jData || env->ExceptionCheck())
- {
- return OC_STACK_ERROR;
- }
-
- str = (char*) env->GetStringUTFChars(jData, 0);
- convertStrToUUID(str, acl->owners[i]);
env->ReleaseStringUTFChars(jData, str);
}
+ else
+ {
+ return OC_STACK_ERROR;
+ }
+
return OC_STACK_OK;
}
return "DUPLICATE_UUID";
case OC_STACK_INCONSISTENT_DB:
return "INCONSISTENT_DB";
+ /** Error code from OTM */
+ case OC_STACK_AUTHENTICATION_FAILURE:
+ return "AUTHENTICATION_FAILURE";
/** Insert all new error codes here!.*/
#ifdef WITH_PRESENCE
case OC_STACK_PRESENCE_STOPPED:
PDM_IS_NOT_INITIALIZED("PDM_IS_NOT_INITIALIZED", ""),
DUPLICATE_UUID("DUPLICATE_UUID", ""),
INCONSISTENT_DB("INCONSISTENT_DB", ""),
+ /** Error code from OTM */
+ AUTHENTICATION_FAILURE("AUTHENTICATION_FAILURE",
+ "This error is pushed from DTLS interface when handshake failure happens"),
/** Insert all new error codes here!.*/
PRESENCE_STOPPED("PRESENCE_STOPPED", ""),
PRESENCE_TIMEOUT("PRESENCE_TIMEOUT", ""),
package org.iotivity.base;
import org.iotivity.ca.CaInterface;
+import org.iotivity.base.BuildConfig;
import java.util.EnumSet;
import java.util.Iterator;
System.loadLibrary("octbstack");
System.loadLibrary("connectivity_abstraction");
System.loadLibrary("oc");
+ if (0 != BuildConfig.SECURED)
+ {
+ System.loadLibrary("ocprovision");
+ }
System.loadLibrary("ocstack-jni");
}
private List<String> resources;
private List<String> periods;
private List<String> recurrences;
- private List<String> owners;
+ private String rownerID;
public OicSecAcl(String subject, List<String> recurrences, List<String> periods, int permission,
- List<String> resources, List<String> owners) {
+ List<String> resources, String rownerID) {
this.subject = subject;
this.recurrences = recurrences;
this.periods = periods;
this.permission = permission;
this.resources = resources;
- this.owners = owners;
+ this.rownerID = rownerID;
}
public String getSubject() {
this.subject = subject;
}
- public List<String> getOwners() {
- return owners;
- }
- public void setOwners(List<String> owners) {
- this.owners = owners;
+ public void setRownerID(String rownerID) {
+ this.rownerID = rownerID;
}
public List<String> getRecurrences() {
return this.recurrences.get(i);
}
- public int getOwnersCount() {
- return this.owners.size();
- }
-
- public String getOwners(int i) {
- return this.owners.get(i);
+ public String getRownerID() {
+ return this.rownerID;
}
}
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/amacl"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlEMA=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlEMA=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlEMA==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlEMA==",
- "ownr": "YWRtaW5EZXZpY2VVVUlEMA=="
- }
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/amacl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } \r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "61646D69-6E44-6576-6963-655575696430"\r
+ }, \r
+ "pstat": {\r
+ "isop": true,\r
+ "cm": 2,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3,\r
+ "deviceuuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "rowneruuid": "61646D69-6E44-6576-6963-655575696430"\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "dpc": false,\r
+ "devowneruuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "rowneruuid": "61646D69-6E44-6576-6963-655575696430"\r
+ }\r
+}\r
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;
+
+import org.iotivity.base.CredType;
+import org.iotivity.base.DeviceStatus;
+import org.iotivity.base.KeySize;
import org.iotivity.base.ModeType;
import org.iotivity.base.OcException;
import org.iotivity.base.OcPlatform;
-import org.iotivity.base.PlatformConfig;
-import org.iotivity.base.QualityOfService;
-import org.iotivity.base.ServiceType;
import org.iotivity.base.OcProvisioning;
import org.iotivity.base.OcSecureResource;
-import org.iotivity.base.ProvisionResult;
-import org.iotivity.base.OxmType;
import org.iotivity.base.OicSecAcl;
-import org.iotivity.base.CredType;
-import org.iotivity.base.KeySize;
-import org.iotivity.base.DeviceStatus;
+import org.iotivity.base.OxmType;
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.ProvisionResult;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.List;
public class ProvisioningClient extends Activity implements
- OcSecureResource.DoOwnershipTransferListener,OcSecureResource.ProvisionPairwiseDevicesListener {
+ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwiseDevicesListener {
private static final String TAG = "Provisioning Client: ";
private static final int BUFFER_SIZE = 1024;
int unownedDevCount = StringConstants.NUMBER_ZERO;
- private String filePath = "";
- private OcSecureResource newSecureResource;
- private List<OcSecureResource> deviceList;
- private List<OcSecureResource> ownedDeviceList;
- private TextView mEventsTextView;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_secure_provision_client);
- mEventsTextView = new TextView(this);
- mEventsTextView.setGravity(Gravity.BOTTOM);
- mEventsTextView.setMovementMethod(new ScrollingMovementMethod());
- LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
- layout.addView(mEventsTextView, new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)
- );
- filePath = getFilesDir().getPath() + "/"; // data/data/<package>/files/
- //copy json when application runs first time
- SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
- boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
- if (isFirstRun) {
- copyJsonFromAsset();
- SharedPreferences.Editor editor = wmbPreference.edit();
- editor.putBoolean("FIRSTRUN", false);
- editor.commit();
- }
- initOICStack();
- }
-
OcProvisioning.PinCallbackListener pinCallbackListener =
new OcProvisioning.PinCallbackListener() {
@Override
return "";
}
};
-
+ private String filePath = "";
+ private OcSecureResource newSecureResource;
+ private List<OcSecureResource> deviceList;
+ private List<OcSecureResource> ownedDeviceList;
+ private TextView mEventsTextView;
OcSecureResource.ProvisionAclListener provisionAclListener =
new OcSecureResource.ProvisionAclListener() {
@Override
}
}
};
-
OcSecureResource.ProvisionCredentialsListener provisionCredentialsListener =
new OcSecureResource.ProvisionCredentialsListener() {
@Override
}
}
};
-
OcSecureResource.UnlinkDevicesListener unlinkDevicesListener =
new OcSecureResource.UnlinkDevicesListener() {
@Override
}
}
};
-
OcSecureResource.RemoveDeviceListener removeDeviceListener =
new OcSecureResource.RemoveDeviceListener() {
@Override
}
};
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_secure_provision_client);
+ mEventsTextView = new TextView(this);
+ mEventsTextView.setGravity(Gravity.BOTTOM);
+ mEventsTextView.setMovementMethod(new ScrollingMovementMethod());
+ LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
+ layout.addView(mEventsTextView, new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)
+ );
+ filePath = getFilesDir().getPath() + "/"; // data/data/<package>/files/
+ //copy CBOR file when application runs first time
+ SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
+ if (isFirstRun) {
+ copyCborFromAsset();
+ SharedPreferences.Editor editor = wmbPreference.edit();
+ editor.putBoolean("FIRSTRUN", false);
+ editor.commit();
+ }
+ initOICStack();
+ }
+
/**
* configure OIC platform and call findResource
*/
ModeType.CLIENT_SERVER,
"0.0.0.0", // bind to all available interfaces
0,
- QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);
+ QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
OcPlatform.Configure(cfg);
try {
/*
newSecureResource = ownedDeviceList.get(0);
OcSecureResource newSecureResource2 = ownedDeviceList.get(1);
List<String> resources = new ArrayList<String>();
- List<String> owners = new ArrayList<String>();
List<String> periods = new ArrayList<String>();
List<String> recurrences = new ArrayList<String>();
- recurrences.add("Daily");
- resources.add("*");
- owners.add("adminDeviceUUID0");
- periods.add("01-01-15");
+ recurrences.add(StringConstants.DEFAULT_RECURRENCES);
+ resources.add(StringConstants.DEFAULT_RESOURCES);
+ periods.add(StringConstants.DEFAULT_PERIOD);
OicSecAcl acl1 = new OicSecAcl(newSecureResource.getDeviceID(), recurrences, periods,
- 31, resources, owners);
+ StringConstants.DEFAULT_PERMISSION, resources, StringConstants.DEFAULT_ROWNER_ID);
OicSecAcl acl2 = new OicSecAcl(newSecureResource2.getDeviceID(), recurrences, periods,
- 31, resources, owners);
+ StringConstants.DEFAULT_PERMISSION, resources, StringConstants.DEFAULT_ROWNER_ID);
newSecureResource.provisionPairwiseDevices(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
KeySize.OWNER_PSK_LENGTH_128, acl1, newSecureResource2, acl2, this);
} catch (Exception e) {
}
/**
- * Copy svr db json file from assets folder to app data files dir
+ * Copy svr db CBOR dat file from assets folder to app data files dir
*/
- private void copyJsonFromAsset() {
+ private void copyCborFromAsset() {
InputStream inputStream = null;
OutputStream outputStream = null;
int length;
byte[] buffer = new byte[BUFFER_SIZE];
try {
- inputStream = getAssets().open(StringConstants.OIC_CLIENT_JSON_DB_FILE);
+ inputStream = getAssets().open(StringConstants.OIC_CLIENT_CBOR_DB_FILE);
File file = new File(filePath);
//check files directory exists
if (!(file.exists() && file.isDirectory())) {
file.mkdirs();
}
- outputStream = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);
+ outputStream = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
logMessage(TAG + "Null pointer exception " + e.getMessage());
Log.e(TAG, e.getMessage());
} catch (FileNotFoundException e) {
- logMessage(TAG + "Json svr db file not found " + e.getMessage());
+ logMessage(TAG + "CBOR svr db file not found " + e.getMessage());
Log.e(TAG, e.getMessage());
} catch (IOException e) {
- logMessage(TAG + StringConstants.OIC_CLIENT_JSON_DB_FILE + " file copy failed");
+ logMessage(TAG + StringConstants.OIC_CLIENT_CBOR_DB_FILE + " file copy failed");
Log.e(TAG, e.getMessage());
} finally {
if (inputStream != null) {
OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
publishProgress(TAG + "ACL Provision for " + ocSecureResource.getDeviceID());
List<String> resources = new ArrayList<String>();
- List<String> owners = new ArrayList<String>();
List<String> periods = new ArrayList<String>();
List<String> recurrences = new ArrayList<String>();
- recurrences.add("Daily");
- resources.add("*");
- owners.add("adminDeviceUUID0");
- periods.add("01-01-15");
+ recurrences.add(StringConstants.DEFAULT_RECURRENCES);
+ resources.add(StringConstants.DEFAULT_RESOURCES);
+ periods.add(StringConstants.DEFAULT_PERIOD);
OicSecAcl aclObject = new OicSecAcl(ocSecureResourceDest.getDeviceID(),
- recurrences, periods, 31, resources, owners);
+ recurrences, periods, StringConstants.DEFAULT_PERMISSION, resources,
+ StringConstants.DEFAULT_ROWNER_ID);
ocSecureResource.provisionACL(aclObject, provisionAclListener);
} else {
publishProgress(TAG + "No Owned devices present");
List<String> linkedDevices = ocSecureResource.getLinkedDevices();
if (linkedDevices.size() > 0) {
for (int i = 0; i < linkedDevices.size(); i++) {
- publishProgress(TAG + "Linked Devices "+
+ publishProgress(TAG + "Linked Devices " +
(i + 1) + "= " + linkedDevices.get(i));
}
} else {
try {
publishProgress(TAG + "Initiate Owned device Discovery");
ownedDeviceList = OcProvisioning.discoverOwnedDevices
- (StringConstants.DISCOVERY_TIMEOUT_10);
+ (StringConstants.DISCOVERY_TIMEOUT_10);
if (ownedDeviceList.size() > 0) {
for (int i = 0; i < ownedDeviceList.size(); i++) {
publishProgress(TAG + "Owned Discovered Device " + (i + 1) + "= " +
public static final int DISCOVERY_TIMEOUT_10 = 10;
public static final int DISCOVERY_TIMEOUT_20 = 20;
public static final int ERROR_CODE = 1;
- public static final String OIC_CLIENT_JSON_DB_FILE = "oic_svr_db_client.json";
+ public static final String DEFAULT_ROWNER_ID = "61646d69-6e44-6576-6963-655555494430";
+ public static final String DEFAULT_RESOURCES = "*";
+ public static final String DEFAULT_RECURRENCES = "Daily";
+ public static final String DEFAULT_PERIOD = "12-12-16";
+ public static final int DEFAULT_PERMISSION = 31;
+ public static final String OIC_CLIENT_CBOR_DB_FILE = "oic_svr_db_client.dat";
public static final String MESSAGE = "message";
public static final String OIC_SQL_DB_FILE = "Pdm.db";
public static final int CREDENTIAL_TYPE=1;
-include ':simpleserver', ':simpleclient', ':fridgeserver', ':fridgeclient', ':guiclient', ':provisioningclient', ':presenceserver', ':presenceclient', ':devicediscoveryclient', ':devicediscoveryserver', ':groupclient', ':groupserver', ':fridgegroupclient', ':fridgegroupserver', ':simplebase'
+include ':simpleserver', ':simpleclient', ':fridgeserver', ':fridgeclient', ':guiclient', ':presenceserver', ':presenceclient', ':devicediscoveryclient', ':devicediscoveryserver', ':groupclient', ':groupserver', ':fridgegroupclient', ':fridgegroupserver'
+SECURED=System.getProperty('SECURE')
+if(SECURED== "1"){
+ include ':provisioningclient'
+}
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl"
- ],
- "perms": 2,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MjIyMjIyMjIyMjIyMjIyMg==",
- "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MTExMTExMTExMTExMTExMQ==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "32323232-3232-3232-3232-323232323232"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+ "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "31313131-3131-3131-3131-313131313131",\r
+ "credtype": 1,\r
+ "privatedata": {\r
+ "data": "AAAAAAAAAAAAAAAA",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232"\r
+ }\r
+}
\ No newline at end of file
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": ["/light0", "/light1", "/a/light"],
- "perms": 6,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MTExMTExMTExMTExMTExMQ==",
- "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/a/light",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/a/light0",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/a/light1",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "31313131-3131-3131-3131-313131313131"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+ "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "32323232-3232-3232-3232-323232323232",\r
+ "credtype": 1,\r
+ "privatedata": {\r
+ "data": "AAAAAAAAAAAAAAAA",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131"\r
+ }\r
+}\r
+\r
2) Build a CloudStack. If you are building first time, then build the stack.
go to "stack" folder in root directory
- $ mvn install
+ $ mvn install -Dmaven.test.skip=true
3) Build a .jar file
- $ mvn install
+ $ mvn install -Dmaven.test.skip=true
- The CloudAccount-0.0.1-SNAPSHOT.jar file will be placed in the "target" folder
package org.iotivity.cloud.accountserver;
import java.net.InetSocketAddress;
+import java.util.Scanner;
import org.iotivity.cloud.accountserver.resources.AccountResource;
import org.iotivity.cloud.accountserver.resources.AuthResource;
import org.iotivity.cloud.base.CoapServer;
import org.iotivity.cloud.base.ResourceManager;
import org.iotivity.cloud.util.Logger;
-import org.iotivity.cloud.util.Net;
/**
- *
- * This class is in charge of running account server.
- *
+ *
+ * This class is in charge of running of account server.
+ *
*/
public class AccountServer {
public static void main(String[] args) throws Exception {
System.out.println("-----Account SERVER-----");
- String hostAddress = Net.getMyIpAddress();
- if (hostAddress.equals("") == true) {
- Logger.e("cannot find host address.");
- return;
- }
if (args.length != 1) {
Logger.e("coap server port required");
coapServer
.startServer(new InetSocketAddress(Integer.parseInt(args[0])));
- }
+ Scanner in = new Scanner(System.in, "UTF-8");
+
+ System.out.println("press 'q' to terminate");
+
+ while (!in.nextLine().equals("q"));
+
+ in.close();
+
+ System.out.println("Terminating...");
+
+ coapServer.stopServer();
+
+ System.out.println("Terminated");
+ }
}
/**
*
- * This class provides a set of API to handle requests for registering account
- * information of authorized user, and publishing and finding resources.
+ * This class provides a set of APIs to handle requests about account
+ * information of authorized user.
*
*/
public class AccountServerManager {
+ /**
+ * API for requesting user account
+ *
+ * @param userId
+ * user identifier
+ * @param deviceId
+ * device identifier
+ * @return Boolean - true if registered, otherwise false
+ */
public Boolean registerUserAccount(String userId, String deviceId) {
Boolean ret = false;
return ret;
}
+ /**
+ * API for requesting user account and getting session code for registered
+ * user.
+ *
+ * @param userId
+ * user identifier
+ * @return String - session code for registered user
+ */
public String registerUserAccount(String userId) {
String sessionCode = null;
}
/**
- * API for requesting user identifier to interested authorization server
- *
- * @param accessToeken
- * access token
+ * API for requesting user identifier corresponding with authorization
+ * information.
+ *
+ * @param authCode
+ * authorization code
* @param authServer
* authorization server
* @return String - user identifier
return userId;
}
+ /**
+ * API for requesting user identifier corresponding with session code.
+ *
+ * @param sessionCode
+ * session code
+ * @return String - user identifier
+ */
public String requestUserId(String sessionCode) {
String userId = null;
}
/**
- * API for getting devices according to authorized user from database
- *
+ * API for getting devices corresponding with user identifier.
+ *
* @param userId
- * identifier of authorized user
+ * user identifier
* @return ArrayList<String> - list of devices
*/
public ArrayList<String> requestAccountDevices(String userId) {
return deviceList;
}
- /**
- * API for requesting access token to interested authorization server
- *
- * @param authServer
- * server name for authorization
- * @param authCode
- * authorization code
- * @return ArrayList<String> - array list of name of authorization servers
- */
private String getAccessToken(String authCode, String authServer) {
String accessToken = null;
- if (authServer.equals(Const.GITHUB)) {
+ if (authServer.equals(Constants.GITHUB)) {
GitHub gitHub = new GitHub();
accessToken = gitHub.requestAccessToken(authCode);
String userId = null;
- if (authServer.equals(Const.GITHUB)) {
+ if (authServer.equals(Constants.GITHUB)) {
GitHub gitHub = new GitHub();
userId = gitHub.requestGetUserInfo(accessToken);
private String generateSessionCode() {
- String sessionCode = "";
+ StringBuffer sessionCode = new StringBuffer();
Random random = new Random();
int randomNum = random.nextInt(122);
|| (randomNum >= 97 && randomNum <= 122)) {
code = (char) randomNum;
- sessionCode += code;
+ sessionCode.append(code);
randomNum = random.nextInt(122);
break;
}
}
- return sessionCode;
+ return sessionCode.toString();
}
}
*/
package org.iotivity.cloud.accountserver;
-public class Const {
+public class Constants {
// MongoDB
public static final String DEVICE_TABLE = "USER_DEVICE";
import java.util.ArrayList;
-import org.iotivity.cloud.accountserver.Const;
+import org.iotivity.cloud.accountserver.Constants;
/**
*
try {
- mongoDB = new MongoDB(Const.DB_NAME);
+ mongoDB = new MongoDB(Constants.DB_NAME);
- mongoDB.createTable(Const.DEVICE_TABLE);
- mongoDB.createTable(Const.SESSION_TABLE);
+ mongoDB.createTable(Constants.DEVICE_TABLE);
+ mongoDB.createTable(Constants.SESSION_TABLE);
registerAdminAccount();
return accoutDBManager;
}
- private void registerAdminAccount() {
-
- String adminId = "admin";
- String adminSessionCode = "00000000";
-
- UserSession userSession = new UserSession();
-
- userSession.setUserId(adminId);
- userSession.setSessionCode(adminSessionCode);
-
- mongoDB.createResource(userSession);
- mongoDB.printResources();
- }
-
/**
- * API for storing session information of authorized user to mongoDB
- *
+ * API for storing session information of authorized user
+ *
* @param userId
- * identifier of authorized user
+ * user identifier
* @param sessionCode
* session code
- * @return Boolean - true if stored, false if not
+ * @return Boolean - true if stored, otherwise false
*/
public Boolean registerUserSessionCode(String userId, String sessionCode) {
return true;
}
+ /**
+ * API for storing device information of authorized user
+ *
+ * @param userId
+ * user identifier
+ * @param deviceId
+ * device identifier
+ * @return Boolean - true if stored, otherwise false
+ */
public Boolean registerUserDevice(String userId, String deviceId) {
UserDevice userDevice = new UserDevice();
return true;
}
+ /**
+ * API for getting user identifier information corresponding with session
+ * code
+ *
+ * @param userId
+ * identifier of authorized user
+ * @param sessionCode
+ * session code
+ * @return Boolean - true if stored, otherwise false
+ */
public String getUserId(String sessionCode) {
String userId = null;
}
/**
- * API for getting devices according to authorized user
- *
+ * API for getting devices corresponding with user identifier
+ *
* @param userId
- * identifier of authorized user
+ * user identifier
* @return ArrayList<String> - list of devices
*/
public ArrayList<String> getDevices(String userId) {
- ArrayList<String> deviceList = new ArrayList<String>();
-
- deviceList = mongoDB.getDevices(userId);
+ ArrayList<String> deviceList = mongoDB.getDevices(userId);
return deviceList;
}
+
+ private void registerAdminAccount() {
+
+ String adminId = "admin";
+ String adminSessionCode = "00000000";
+
+ UserSession userSession = new UserSession();
+
+ userSession.setUserId(adminId);
+ userSession.setSessionCode(adminSessionCode);
+
+ mongoDB.createResource(userSession);
+ mongoDB.printResources();
+ }
}
import java.util.ArrayList;
import org.bson.Document;
-import org.iotivity.cloud.accountserver.Const;
+import org.iotivity.cloud.accountserver.Constants;
import org.iotivity.cloud.util.Logger;
import com.mongodb.MongoClient;
* @throws Exception
*/
public MongoDB(String dbname) throws Exception {
+
mongoClient = new MongoClient();
mongoClient.dropDatabase(dbname);
db = mongoClient.getDatabase(dbname);
* collection name
*/
public void createTable(String tableName) {
+
db.createCollection(tableName);
}
* collection name
*/
public void deleteTable(String tableName) {
+
db.getCollection(tableName).drop();
}
+ /**
+ * API getting database object
+ *
+ */
public MongoDatabase getMongoDatabase() {
+
return db;
}
/**
- * API for storing information of authorized users
+ * API for storing session information of user
*
- * @param accountInfo
- * information of authorized users
- * @param tablename
- * table name of mongoDB
+ * @param UserSession
+ * session information of user
*/
public void createResource(UserSession userSession) {
Document doc = createDocument(userSession);
MongoCollection<Document> collection = db
- .getCollection(Const.SESSION_TABLE);
+ .getCollection(Constants.SESSION_TABLE);
if (collection.findOneAndReplace(Filters.and(
- Filters.eq(Const.USER_ID, doc.get(Const.USER_ID)),
- Filters.eq(Const.SESSION_CODE, doc.get(Const.SESSION_CODE))),
+ Filters.eq(Constants.USER_ID, doc.get(Constants.USER_ID)),
+ Filters.eq(Constants.SESSION_CODE, doc.get(Constants.SESSION_CODE))),
doc) == null) {
collection.insertOne(doc);
return;
}
+ /**
+ * API for inserting device information of user
+ *
+ * @param UserDevice
+ * device information of user
+ */
public void createResource(UserDevice userDevice) {
Document doc = createDocument(userDevice);
MongoCollection<Document> collection = db
- .getCollection(Const.DEVICE_TABLE);
+ .getCollection(Constants.DEVICE_TABLE);
- if (collection.findOneAndReplace(
- Filters.and(Filters.eq(Const.USER_ID, doc.get(Const.USER_ID)),
- Filters.eq(Const.DEVICE_ID, doc.get(Const.DEVICE_ID))),
- doc) == null) {
+ if (collection.findOneAndReplace(Filters.and(
+ Filters.eq(Constants.USER_ID, doc.get(Constants.USER_ID)),
+ Filters.eq(Constants.DEVICE_ID, doc.get(Constants.DEVICE_ID))), doc) == null) {
collection.insertOne(doc);
}
return;
}
- private Document createDocument(UserSession userSession) {
-
- Document doc = new Document(Const.USER_ID, userSession.getUserId())
- .append(Const.SESSION_CODE, userSession.getSessionCode());
-
- return doc;
- }
-
- private Document createDocument(UserDevice userDevice) {
-
- Document doc = new Document(Const.USER_ID, userDevice.getUserId())
- .append(Const.DEVICE_ID, userDevice.getDeviceId());
-
- return doc;
- }
-
- private UserSession convertSessionDocToResource(Document doc) {
-
- UserSession userSession = new UserSession();
-
- userSession.setUserId(doc.getString(Const.USER_ID));
- userSession.setSessionCode(doc.getString(Const.SESSION_CODE));
-
- return userSession;
- }
-
- private UserDevice convertDeviceDocToResource(Document doc) {
-
- UserDevice userDevice = new UserDevice();
-
- userDevice.setUserId(doc.getString(Const.USER_ID));
- userDevice.setDeviceId(doc.getString(Const.DEVICE_ID));
-
- return userDevice;
- }
-
+ /**
+ * API for getting user identifier corresponding with session code from
+ * database
+ *
+ * @param sessionCode
+ * session code
+ * @return String - user identifier
+ */
public String getUserId(String sessionCode) {
String userId = null;
MongoCollection<Document> collection = db
- .getCollection(Const.SESSION_TABLE);
+ .getCollection(Constants.SESSION_TABLE);
- MongoCursor<Document> cursor = collection
- .find(Filters.eq(Const.SESSION_CODE, sessionCode)).iterator();
+ MongoCursor<Document> cursor = collection.find(
+ Filters.eq(Constants.SESSION_CODE, sessionCode)).iterator();
try {
}
/**
- * API for getting devices according to user from mongoDB
+ * API for getting devices corresponding with user identifier from database
*
* @param userId
* user identifier
- * @param tablename
- * table name of mongoDB
*/
public ArrayList<String> getDevices(String userId) {
ArrayList<String> deviceList = new ArrayList<String>();
MongoCollection<Document> collection = db
- .getCollection(Const.DEVICE_TABLE);
+ .getCollection(Constants.DEVICE_TABLE);
- MongoCursor<Document> cursor = collection
- .find(Filters.eq(Const.USER_ID, userId)).iterator();
+ MongoCursor<Document> cursor = collection.find(
+ Filters.eq(Constants.USER_ID, userId)).iterator();
try {
return deviceList;
}
+ public void printResources() {
+
+ ArrayList<UserDevice> dlist = readDeviceResources();
+ int size = dlist.size();
+
+ Logger.i("*Table: " + Constants.DEVICE_TABLE);
+ for (int i = 0; i < size; i++) {
+
+ UserDevice item = dlist.get(i);
+
+ Logger.i("[" + i + "]" + item.getUserId() + ", "
+ + item.getDeviceId());
+ }
+
+ ArrayList<UserSession> slist = readSessionResources();
+ size = slist.size();
+
+ Logger.i("*Table: " + Constants.SESSION_TABLE);
+
+ for (int i = 0; i < size; i++) {
+
+ UserSession item = slist.get(i);
+
+ Logger.i("[" + i + "]" + item.getUserId() + ", "
+ + item.getSessionCode());
+
+ }
+ }
+
+ private Document createDocument(UserSession userSession) {
+
+ Document doc = new Document(Constants.USER_ID, userSession.getUserId())
+ .append(Constants.SESSION_CODE, userSession.getSessionCode());
+
+ return doc;
+ }
+
+ private Document createDocument(UserDevice userDevice) {
+
+ Document doc = new Document(Constants.USER_ID, userDevice.getUserId())
+ .append(Constants.DEVICE_ID, userDevice.getDeviceId());
+
+ return doc;
+ }
+
+ private UserSession convertSessionDocToResource(Document doc) {
+
+ UserSession userSession = new UserSession();
+
+ userSession.setUserId(doc.getString(Constants.USER_ID));
+ userSession.setSessionCode(doc.getString(Constants.SESSION_CODE));
+
+ return userSession;
+ }
+
+ private UserDevice convertDeviceDocToResource(Document doc) {
+
+ UserDevice userDevice = new UserDevice();
+
+ userDevice.setUserId(doc.getString(Constants.USER_ID));
+ userDevice.setDeviceId(doc.getString(Constants.DEVICE_ID));
+
+ return userDevice;
+ }
+
private ArrayList<UserSession> readSessionResources() {
ArrayList<UserSession> userSessionList = new ArrayList<UserSession>();
MongoCollection<Document> collection = db
- .getCollection(Const.SESSION_TABLE);
+ .getCollection(Constants.SESSION_TABLE);
MongoCursor<Document> cursor = collection.find().iterator();
while (cursor.hasNext()) {
ArrayList<UserDevice> userDeviceList = new ArrayList<UserDevice>();
MongoCollection<Document> collection = db
- .getCollection(Const.DEVICE_TABLE);
+ .getCollection(Constants.DEVICE_TABLE);
MongoCursor<Document> cursor = collection.find().iterator();
while (cursor.hasNext()) {
return userDeviceList;
}
- public void printResources() {
-
- ArrayList<UserDevice> dlist = readDeviceResources();
- int size = dlist.size();
-
- Logger.i("*Table: " + Const.DEVICE_TABLE);
- for (int i = 0; i < size; i++) {
-
- UserDevice item = dlist.get(i);
-
- Logger.i("[" + i + "]" + item.getUserId() + ", "
- + item.getDeviceId());
- }
-
- ArrayList<UserSession> slist = readSessionResources();
- size = slist.size();
-
- Logger.i("*Table: " + Const.SESSION_TABLE);
-
- for (int i = 0; i < size; i++) {
-
- UserSession item = slist.get(i);
-
- Logger.i("[" + i + "]" + item.getUserId() + ", "
- + item.getSessionCode());
-
- }
- }
-
}
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.types.GrantType;
-import org.iotivity.cloud.accountserver.util.JSONUtil;
+import org.iotivity.cloud.util.JSONUtil;
import org.iotivity.cloud.util.Logger;
/**
@Override
public String requestGetUserInfo(String accessToken) {
- String userInfo = "{}";
+ String userInfo = null;
+
+ if (accessToken == null) {
+ Logger.w("accessToken is null!");
+ return null;
+ }
try {
OAuthClientRequest request = new OAuthBearerClientRequest(
resource_url).setAccessToken(accessToken)
- .buildQueryMessage();
+ .buildQueryMessage();
- OAuthClient oAuthClient = new OAuthClient(
- new URLConnectionClient());
+ OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
+
OAuthResourceResponse resourceResponse = oAuthClient.resource(
request, OAuth.HttpMethod.GET, OAuthResourceResponse.class);
e.printStackTrace();
}
- JSONUtil util = new JSONUtil();
String userIdKey = "login";
- String userId = util.parseJSON(userInfo, userIdKey);
+ String userId = JSONUtil.parseJSON(userInfo, userIdKey);
return userId;
}
import java.util.List;
import org.iotivity.cloud.accountserver.AccountServerManager;
-import org.iotivity.cloud.accountserver.Const;
+import org.iotivity.cloud.accountserver.Constants;
import org.iotivity.cloud.accountserver.util.CoapMessageBuilder;
-import org.iotivity.cloud.accountserver.util.JSONUtil;
import org.iotivity.cloud.base.Resource;
import org.iotivity.cloud.base.protocols.coap.CoapRequest;
import org.iotivity.cloud.base.protocols.coap.CoapResponse;
import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
+import org.iotivity.cloud.util.JSONUtil;
import org.iotivity.cloud.util.Logger;
import io.netty.channel.ChannelHandlerContext;
/**
*
- * This class provides a set of APIs to handle requests for publishing and
- * finding resources.
+ * This class provides a set of APIs to manage resources corresponding with user
+ * account
*
*/
public class AccountResource extends Resource {
public AccountResource() {
- setUri(Const.ACCOUNT_URI);
+ setUri(Constants.ACCOUNT_URI);
}
@Override
}
}
- /**
- * API for handling GET message
- *
- * @param ctx
- * ChannelHandlerContext of request message
- * @param request
- * CoAP request message
- * @throws Exception
- */
private void handleGetRequest(ChannelHandlerContext ctx,
CoapRequest request) throws Exception {
- String reqType = extractQuery(request, Const.REQ_TYPE);
+ String reqType = extractQuery(request, Constants.REQ_TYPE);
if (reqType == null)
throw new IllegalArgumentException(
CoapResponse response = null;
switch (reqType) {
-
- case Const.TYPE_FIND:
+ case Constants.TYPE_FIND:
response = handleFindRequest(request);
break;
default:
Logger.w("reqType[" + reqType + "] is not supported");
}
-
- ctx.write(response);
+ if (response != null) {
+ ctx.writeAndFlush(response);
+ }
}
- /**
- * API for handling POST message
- *
- * @param ctx
- * ChannelHandlerContext of request message
- * @param request
- * CoAP request message
- * @throws Exception
- */
private void handlePostRequest(ChannelHandlerContext ctx,
CoapRequest request) throws Exception {
- String reqType = extractQuery(request, Const.REQ_TYPE);
+ String reqType = extractQuery(request, Constants.REQ_TYPE);
if (reqType == null)
throw new IllegalArgumentException(
"request type is null in query!");
- CoapResponse response = null;
+ CoapResponse response;
switch (reqType) {
- case Const.TYPE_PUBLISH:
+ case Constants.TYPE_PUBLISH:
response = handlePublishRequest(request);
break;
default:
"request type is not supported");
}
- ctx.write(response);
+ ctx.writeAndFlush(response);
}
+ /**
+ * API for handling request for publishing resource corresponding with user
+ * account
+ *
+ * @param requeset
+ * CoAP request message
+ * @return CoapResponse - CoAP response message with response result
+ * information
+ */
private CoapResponse handlePublishRequest(CoapRequest request) {
String payload = request.getPayloadString();
- JSONUtil util = new JSONUtil();
- String userId = util.parseJSON(payload, Const.REQUEST_USER_ID);
- String deviceId = util.parseJSON(payload, Const.REQUEST_DEVICE_ID);
+ String userId = JSONUtil.parseJSON(payload, Constants.REQUEST_USER_ID);
+ String deviceId = JSONUtil.parseJSON(payload,
+ Constants.REQUEST_DEVICE_ID);
Logger.d("userId: " + userId + ", deviceId: " + deviceId);
Logger.d("status : " + status);
CoapMessageBuilder responseMessage = new CoapMessageBuilder();
- CoapResponse coapResponse = null;
+ CoapResponse coapResponse;
if (status) {
coapResponse = responseMessage.buildCoapResponse(request.getToken(),
return coapResponse;
}
+ /**
+ * API for handling request for finding resource corresponding with user
+ * account
+ *
+ * @param requeset
+ * CoAP request message
+ * @return CoapResponse - CoAP response message with response result
+ * information
+ */
private CoapResponse handleFindRequest(CoapRequest request) {
String payload = request.getPayloadString();
// String payload = getPayloadString(request.getPayload());
JSONUtil util = new JSONUtil();
- String userId = util.parseJSON(payload, Const.REQUEST_USER_ID);
+ String userId = util.parseJSON(payload, Constants.REQUEST_USER_ID);
Logger.d("userId: " + userId);
HashMap<Object, Object> responseMap = new HashMap<Object, Object>();
ArrayList<String> deviceList = response.getDeviceList();
- responseMap.put(Const.RESPONSE_DEVICES, deviceList);
+ responseMap.put(Constants.RESPONSE_DEVICES, deviceList);
- JSONUtil jsonUtil = new JSONUtil();
- String responseJson = jsonUtil.writeJSON(responseMap);
+ String responseJson = JSONUtil.writeJSON(responseMap);
return responseJson;
}
List<String> Segments = request.getUriQuerySegments();
- for (String s : Segments) {
+ if (Segments != null) {
+ for (String s : Segments) {
- String pair[] = s.split("=");
+ String pair[] = s.split("=");
- if (pair[0].equals(key)) {
+ if (pair[0].equals(key)) {
- value = pair[1];
+ value = pair[1];
+ }
}
}
/*
* private static String getPayloadString(byte[] payload) {
- *
+ *
* if (payload == null) return "";
- *
+ *
* return new String(payload, Charset.forName("UTF-8")); }
*/
import java.util.List;
import org.iotivity.cloud.accountserver.AccountServerManager;
-import org.iotivity.cloud.accountserver.Const;
+import org.iotivity.cloud.accountserver.Constants;
import org.iotivity.cloud.accountserver.util.CoapMessageBuilder;
-import org.iotivity.cloud.accountserver.util.JSONUtil;
import org.iotivity.cloud.base.Resource;
import org.iotivity.cloud.base.protocols.coap.CoapRequest;
import org.iotivity.cloud.base.protocols.coap.CoapResponse;
import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
+import org.iotivity.cloud.util.JSONUtil;
import org.iotivity.cloud.util.Logger;
import io.netty.channel.ChannelHandlerContext;
/**
*
- * This class provides a set of APIs to register account information of
- * authorized user.
+ * This class provides a set of APIs to manage user account with authorization
+ * process.
*
*/
public class AuthResource extends Resource {
public AuthResource() {
- setUri(Const.AUTH_URI);
+ setUri(Constants.AUTH_URI);
}
@Override
- public void onRequestReceived(ChannelHandlerContext ctx, CoapRequest request) {
+ public void onRequestReceived(ChannelHandlerContext ctx,
+ CoapRequest request) {
Logger.d("AuthResource IN");
}
}
- /**
- * API for handling POST message
- *
- * @param ctx
- * ChannelHandlerContext of request message
- * @param request
- * CoAP request message
- * @throws Exception
- */
private void handlePostRequest(ChannelHandlerContext ctx,
CoapRequest request) throws Exception {
- String reqType = extractQuery(request, Const.REQ_TYPE);
+ String reqType = extractQuery(request, Constants.REQ_TYPE);
if (reqType == null)
- throw new IllegalArgumentException("request type is null in query!");
+ throw new IllegalArgumentException(
+ "request type is null in query!");
- CoapResponse response = null;
+ CoapResponse response;
switch (reqType) {
- case Const.TYPE_REGISTER:
+ case Constants.TYPE_REGISTER:
response = handleRegisterRequest(request);
break;
- case Const.TYPE_LOGIN:
+ case Constants.TYPE_LOGIN:
response = handleLoginRequest(request);
break;
default:
"request type is not supported");
}
- ctx.write(response);
+ ctx.writeAndFlush(response);
}
+ /**
+ * API for handling request for login by user account
+ *
+ * @param request
+ * CoAP request message
+ * @return CoapResponse - CoAP response message with response result
+ * information
+ */
private CoapResponse handleLoginRequest(CoapRequest request) {
String payload = request.getPayloadString();
- JSONUtil util = new JSONUtil();
- String sessionCode = util
- .parseJSON(payload, Const.REQUEST_SESSION_CODE);
+ String sessionCode = JSONUtil.parseJSON(payload,
+ Constants.REQUEST_SESSION_CODE);
Logger.d("sessionCode: " + sessionCode);
Logger.d("userId: " + userId);
CoapMessageBuilder responseMessage = new CoapMessageBuilder();
- CoapResponse coapResponse = null;
+ CoapResponse coapResponse;
if (userId != null) {
String responseJson = convertLoginResponseToJson(response);
Logger.d("responseJson: " + responseJson);
- coapResponse = responseMessage.buildCoapResponse(
- request.getToken(), responseJson, CoapStatus.CREATED);
+ coapResponse = responseMessage.buildCoapResponse(request.getToken(),
+ responseJson, CoapStatus.CREATED);
} else {
- coapResponse = responseMessage.buildCoapResponse(
- request.getToken(), CoapStatus.INTERNAL_SERVER_ERROR);
+ coapResponse = responseMessage.buildCoapResponse(request.getToken(),
+ CoapStatus.INTERNAL_SERVER_ERROR);
}
return coapResponse;
}
+ /**
+ * API for handling request for registering user account
+ *
+ * @param request
+ * CoAP request message
+ * @return CoapResponse - CoAP response message with response result
+ * information
+ */
private CoapResponse handleRegisterRequest(CoapRequest request) {
String payload = request.getPayloadString();
- JSONUtil util = new JSONUtil();
- String authCode = util.parseJSON(payload, Const.REQUEST_AUTH_CODE);
- String authServer = util.parseJSON(payload, Const.REQUEST_AUTH_SERVER);
+ String authCode = JSONUtil.parseJSON(payload,
+ Constants.REQUEST_AUTH_CODE);
+ String authServer = JSONUtil.parseJSON(payload,
+ Constants.REQUEST_AUTH_SERVER);
Logger.d("authCode: " + authCode + ", authServer: " + authServer);
AccountServerManager oauthServerManager = new AccountServerManager();
+ String userId = null;
+ if (authCode != null && authServer != null) {
+ userId = oauthServerManager.requestUserId(authCode, authServer);
+ }
+
+ CoapMessageBuilder responseMessage = new CoapMessageBuilder();
+ CoapResponse coapResponse;
- String userId = oauthServerManager.requestUserId(authCode, authServer);
- String sessionCode = oauthServerManager.registerUserAccount(userId);
+ if (userId != null) {
+
+ String sessionCode = oauthServerManager.registerUserAccount(userId);
- Logger.d("userId: " + userId + ", sessionCode: " + sessionCode);
+ Logger.d("userId: " + userId + ", sessionCode: " + sessionCode);
- CoapMessageBuilder responseMessage = new CoapMessageBuilder();
- CoapResponse coapResponse = null;
+ if (sessionCode != null) {
- if (userId != null && sessionCode != null) {
+ ResponseObject response = new ResponseObject();
+ response.setSessionCode(sessionCode);
+ response.setUserId(userId);
- ResponseObject response = new ResponseObject();
- response.setSessionCode(sessionCode);
- response.setUserId(userId);
+ String responseJson = convertRegisterResponseToJson(response);
+ Logger.d("responseJson: " + responseJson);
- String responseJson = convertRegisterResponseToJson(response);
- Logger.d("responseJson: " + responseJson);
-
- coapResponse = responseMessage.buildCoapResponse(
- request.getToken(), responseJson, CoapStatus.CREATED);
+ coapResponse = responseMessage.buildCoapResponse(
+ request.getToken(), responseJson, CoapStatus.CREATED);
+ }
+ else {
+ coapResponse = responseMessage.buildCoapResponse(request.getToken(),
+ CoapStatus.UNAUTHORIZED);
+ }
} else {
- coapResponse = responseMessage.buildCoapResponse(
- request.getToken(), CoapStatus.UNAUTHORIZED);
-
+ coapResponse = responseMessage.buildCoapResponse(request.getToken(),
+ CoapStatus.UNAUTHORIZED);
}
return coapResponse;
String userId = response.getUserId();
if (userId != null)
- responseMap.put(Const.RESPONSE_USER_ID, userId);
+ responseMap.put(Constants.RESPONSE_USER_ID, userId);
if (sessionCode != null)
- responseMap.put(Const.RESPONSE_SESSION_CODE, sessionCode);
+ responseMap.put(Constants.RESPONSE_SESSION_CODE, sessionCode);
- JSONUtil jsonUtil = new JSONUtil();
- String responseJson = jsonUtil.writeJSON(responseMap);
+ String responseJson = JSONUtil.writeJSON(responseMap);
return responseJson;
}
String userId = response.getUserId();
if (userId != null)
- responseMap.put(Const.RESPONSE_USER_ID, userId);
+ responseMap.put(Constants.RESPONSE_USER_ID, userId);
- JSONUtil jsonUtil = new JSONUtil();
- String responseJson = jsonUtil.writeJSON(responseMap);
+ String responseJson = JSONUtil.writeJSON(responseMap);
return responseJson;
}
List<String> Segments = request.getUriQuerySegments();
- for (String s : Segments) {
+ if (Segments != null) {
+ for (String s : Segments) {
- String pair[] = s.split("=");
+ String pair[] = s.split("=");
- if (pair[0].equals(key)) {
+ if (pair[0].equals(key)) {
- value = pair[1];
+ value = pair[1];
+ }
}
}
/*
* private static String getPayloadString(byte[] payload) {
- *
+ *
* if (payload == null) return "";
- *
+ *
* return new String(payload, Charset.forName("UTF-8")); }
*/
/**
*
- * This class provides utility for making CoAP request and response.
+ * This class provides a set of APIs to build build data of CoAP request and
+ * response type.
*
*/
public class CoapMessageBuilder {
public static final int APPLICATION_JSON = 50;
+ /**
+ * API for building data of CoAP response type without payload.
+ *
+ * @param token
+ * token
+ * @param status
+ * response status
+ * @return CoapResponse - data of CoAP response type
+ */
public CoapResponse buildCoapResponse(byte[] token, CoapStatus status) {
return buildCoapResponse(token, null, status);
}
+ /**
+ * API for building data of CoAP response type with payload.
+ *
+ * @param token
+ * token
+ * @param jsonString
+ * payload data
+ * @param status
+ * response status
+ * @return CoapResponse - data of CoAP response type
+ */
public CoapResponse buildCoapResponse(byte[] token, String jsonString,
CoapStatus status) {
return coapResponse;
}
+ /**
+ * API for building data of CoAP requeset type with payload.
+ *
+ * @param token
+ * token
+ * @param jsonString
+ * payload data
+ * @return CoapRequest - data of CoAP request type
+ */
public CoapRequest buildCoapRequest(byte[] token, String jsonString) {
CoapRequest coapRequest = new CoapRequest(CoapMethod.GET);
+++ /dev/null
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.accountserver.util;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-/**
- *
- * This class provides utility for parsing JSON object and converting data to
- * JSON string.
- *
- */
-public class JSONUtil {
-
- private static ObjectMapper mapper = new ObjectMapper();
-
- public String parseJSON(String jsonString, String key) {
-
- if (jsonString == null || jsonString.equals(""))
- return null;
-
- String value = null;
-
- try {
- @SuppressWarnings("unchecked")
- Map<String, String> jsonMap = mapper.readValue(jsonString,
- Map.class);
- value = jsonMap.get(key);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
-
- return value;
- }
-
- public String writeJSON(HashMap<Object, Object> data) {
- if (data == null)
- return null;
-
- String json = null;
- try {
- json = mapper.writeValueAsString(data);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
-
- if (json == null)
- json = "{}";
-
- return json;
- }
-}
import java.nio.charset.StandardCharsets;
import org.junit.Test;
-import org.iotivity.cloud.accountserver.Const;
+import org.iotivity.cloud.accountserver.Constants;
import org.iotivity.cloud.accountserver.resources.AccountResource;
import org.iotivity.cloud.accountserver.resources.AuthResource;
-import org.iotivity.cloud.accountserver.util.JSONUtil;
import org.iotivity.cloud.base.CoapClient;
import org.iotivity.cloud.base.CoapServer;
import org.iotivity.cloud.base.ResourceManager;
import org.iotivity.cloud.base.protocols.coap.CoapRequest;
import org.iotivity.cloud.base.protocols.coap.CoapResponse;
import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
+import org.iotivity.cloud.util.JSONUtil;
public class TestAccountServer {
if (arg1.getTokenString().equals("1111")) {
String json = arg1.getPayloadString();
- JSONUtil util = new JSONUtil();
- sessionCode = util.parseJSON(json, "session");
+ sessionCode = JSONUtil.parseJSON(json, "session");
}
}
System.out
.println("https://github.com/login?return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3Dea9c18f540323b0213d0%26redirect_uri%3Dhttp%253A%252F%252Fwww.example.com%252Foauth_callback%252F");
- String authCode = "a05c2d8f6531ec15230e"; // write your authCode here.
+ String authCode = "7243699de9726d05e74c"; // write your authCode here.
String authServer = "github";
String json = "{\"authcode\":\"" + authCode + "\",\"authprovider\":\""
+ authServer + "\"}";
CoapRequest request = new CoapRequest(CoapMethod.POST);
- request.setUriPath(Const.AUTH_URI);
+ request.setUriPath(Constants.AUTH_URI);
request.setUriQuery("reqtype=register");
request.setToken("1111".getBytes(StandardCharsets.UTF_8));
request.setPayload(json.getBytes(StandardCharsets.UTF_8));
String json = "{\"session\":\"" + sessionCode + "\"}";
CoapRequest request = new CoapRequest(CoapMethod.POST);
- request.setUriPath(Const.AUTH_URI);
+ request.setUriPath(Constants.AUTH_URI);
request.setUriQuery("reqtype=login");
request.setToken("1234".getBytes(StandardCharsets.UTF_8));
request.setPayload(json.getBytes(StandardCharsets.UTF_8));
+ deviceId + "\"}";
CoapRequest request = new CoapRequest(CoapMethod.POST);
- request.setUriPath(Const.ACCOUNT_URI);
+ request.setUriPath(Constants.ACCOUNT_URI);
request.setUriQuery("reqtype=publish");
request.setToken("1234".getBytes(StandardCharsets.UTF_8));
request.setPayload(json.getBytes(StandardCharsets.UTF_8));
String userId = "eyedglen";
String json = "{\"userid\":\"" + userId + "\"}";
- CoapRequest request = new CoapRequest(CoapMethod.POST);
- request.setUriPath(Const.ACCOUNT_URI);
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriPath(Constants.ACCOUNT_URI);
request.setUriQuery("reqtype=find");
request.setToken("1234".getBytes(StandardCharsets.UTF_8));
request.setPayload(json.getBytes(StandardCharsets.UTF_8));
2) Build a CloudStack. If you are building first time, then build the stack.
go to "stack" folder in root directory
- $ mvn install
+ $ mvn install -Dmaven.test.skip=true
3) Build a .jar file
- $ mvn install
+ $ mvn install -Dmaven.test.skip=true
- The CloudInterface-0.0.1-SNAPSHOT.jar file will be placed in the "target" folder
package org.iotivity.cloud.ciserver;
import java.net.InetSocketAddress;
+import java.util.Scanner;
import org.iotivity.cloud.base.CoapServer;
import org.iotivity.cloud.base.ResourceManager;
import org.iotivity.cloud.ciserver.resources.KeepAliveResource;
import org.iotivity.cloud.util.CoapLogHandler;
import org.iotivity.cloud.util.Logger;
-import org.iotivity.cloud.util.Net;
public class CloudInterfaceServer {
public static void main(String[] args) throws Exception {
System.out.println("-----CI SERVER-------");
- String hostAddress = Net.getMyIpAddress();
- if (hostAddress.equals("") == true) {
- Logger.e("cannot find host address.");
- return;
- }
if (args.length != 5) {
Logger.e(
SessionManager sessionManager = null;
CoapServer coapServer = null;
+ CoapRelayHandler relayHandler = null;
+ CoapAuthHandler authHandler = null;
+
+ KeepAliveResource keepAliveResource = null;
+
coapServer = new CoapServer();
sessionManager = new SessionManager();
- resourceManager = new ResourceManager(sessionManager);
+ resourceManager = new ResourceManager();
+
+ relayHandler = new CoapRelayHandler(sessionManager);
- coapServer.addHandler(
- new CoapAuthHandler(args[3], Integer.parseInt(args[4])));
+ authHandler = new CoapAuthHandler();
+
+ keepAliveResource = new KeepAliveResource(sessionManager,
+ new int[] { 1, 2, 4, 8 });
coapServer.addHandler(new CoapLogHandler());
- // Comment the following one line to make CI server run alone
- coapServer.addHandler(new CoapRelayHandler(sessionManager, args[1],
- Integer.parseInt(args[2]), args[3], Integer.parseInt(args[4])));
+ coapServer.addHandler(authHandler);
+
+ coapServer.addHandler(relayHandler);
coapServer.addHandler(resourceManager);
- resourceManager.registerResource(new KeepAliveResource(sessionManager,
- new int[] { 1, 2, 4, 8 }));
+ resourceManager.registerResource(keepAliveResource);
+
+ authHandler.startHandler(args[3], Integer.parseInt(args[4]));
+
+ relayHandler.startHandler(args[1], Integer.parseInt(args[2]), args[3],
+ Integer.parseInt(args[4]));
coapServer
.startServer(new InetSocketAddress(Integer.parseInt(args[0])));
+
+ keepAliveResource.startSessionChecker();
+
+ Scanner in = new Scanner(System.in, "UTF-8");
+
+ System.out.println("press 'q' to terminate");
+
+ while (!in.nextLine().equals("q"));
+
+ in.close();
+
+ System.out.println("Terminating...");
+
+ keepAliveResource.stopSessionChecker();
+
+ coapServer.stopServer();
+
+ relayHandler.stopHandler();
+
+ authHandler.stopHandler();
+
+ System.out.println("Terminated");
}
}
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2016 Samsung Electronics All Rights Reserved.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ * //
+ * // Licensed under the Apache License, Version 2.0 (the "License");
+ * // you may not use this file except in compliance with the License.
+ * // You may obtain a copy of the License at
+ * //
+ * // http://www.apache.org/licenses/LICENSE-2.0
+ * //
+ * // Unless required by applicable law or agreed to in writing, software
+ * // distributed under the License is distributed on an "AS IS" BASIS,
+ * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * // See the License for the specific language governing permissions and
+ * // limitations under the License.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
package org.iotivity.cloud.ciserver.protocols;
import java.net.InetSocketAddress;
.attr(keyAuthClient).get();
if (msg.getResponseCode() == CoapStatus.CREATED) {
- Map<String, String> response = JSONUtil
- .parseJSON(new String(msg.getPayload(), StandardCharsets.UTF_8));
+ Map<String, String> response = JSONUtil.parseJSON(
+ new String(msg.getPayload(), StandardCharsets.UTF_8));
- String userId = response.get("userid");
- if (userId != null) {
- ctxToDevice.channel().attr(Constants.Attribute_UserId)
- .set(userId);
- }
- msg.setPayload(cbor.encodingPayloadToCbor(response));
+ if (response != null) {
+ String userId = response.get("userid");
+ if (userId != null) {
+ ctxToDevice.channel().attr(Constants.Attribute_UserId)
+ .set(userId);
+ }
+ msg.setPayload(cbor.encodingPayloadToCbor(response));
- CoapAuthHandler authHandler = ctxToDevice.channel().pipeline()
- .get(CoapAuthHandler.class);
+ CoapAuthHandler authHandler = ctxToDevice.channel()
+ .pipeline().get(CoapAuthHandler.class);
- ctxToDevice.channel().pipeline().remove(authHandler);
+ ctxToDevice.channel().pipeline().remove(authHandler);
+ }
}
ctxToDevice.writeAndFlush(msg);
}
}
- private CoapClient accountClient = new CoapClient();
+ private CoapClient asClient = new CoapClient();
- public CoapAuthHandler(String accountAddress, int accountPort) {
+ public CoapAuthHandler() {
+
+ asClient.addHandler(new AccountHandler());
- accountClient.addHandler(new AccountHandler());
- try {
- accountClient.startClient(
- new InetSocketAddress(accountAddress, accountPort));
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ }
+
+ public void startHandler(String acAddress, int acPort) throws Exception {
+ asClient.startClient(new InetSocketAddress(acAddress, acPort));
+ }
+
+ public void stopHandler() throws Exception {
+ asClient.stopClient();
}
private Cbor<HashMap<Object, Object>> cbor = new Cbor<HashMap<Object, Object>>();
if (msg instanceof CoapRequest) {
CoapRequest request = (CoapRequest) msg;
- switch (request.getUriPath()) {
- // This handler only used for initial handshake
- case Constants.AUTH_URI:
- HashMap<Object, Object> payloadData = cbor
- .parsePayloadFromCbor(request.getPayload(),
- HashMap.class);
- request.setPayload(
- JSONUtil.writeJSON(payloadData).getBytes(StandardCharsets.UTF_8));
- accountClient.getChannelFuture().channel()
- .attr(keyAuthClient).set(ctx);
- accountClient.sendRequest(request);
- return;
-
- case Constants.KEEP_ALIVE_URI:
- super.channelRead(ctx, msg);
- return;
-
- default:
- CoapResponse response = new CoapResponse(
- CoapStatus.UNAUTHORIZED);
- Logger.e("Sending UNAUTHORIZED to client");
- ctx.writeAndFlush(response);
- break;
+ String uriPath = request.getUriPath();
+ if (uriPath != null) {
+ switch (uriPath) {
+ // This handler only used for initial handshake
+ case Constants.AUTH_URI:
+ HashMap<Object, Object> payloadData = cbor
+ .parsePayloadFromCbor(request.getPayload(),
+ HashMap.class);
+ String writejson = JSONUtil.writeJSON(payloadData);
+ if (writejson != null) {
+ request.setPayload(
+ writejson.getBytes(StandardCharsets.UTF_8));
+ asClient.getChannelFuture().channel()
+ .attr(keyAuthClient).set(ctx);
+ asClient.sendRequest(request);
+ }
+ return;
+
+ case Constants.KEEP_ALIVE_URI:
+ super.channelRead(ctx, msg);
+ return;
+
+ default:
+ CoapResponse response = new CoapResponse(
+ CoapStatus.UNAUTHORIZED);
+ Logger.e("Sending UNAUTHORIZED to client");
+ ctx.writeAndFlush(response);
+ break;
+ }
}
}
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
import org.iotivity.cloud.base.CoapClient;
import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
import org.iotivity.cloud.ciserver.Constants;
import org.iotivity.cloud.util.Logger;
-import org.iotivity.cloud.util.Net;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandler.Sharable;
}
}
- private CoapClient rdClient = new CoapClient();
- ///////////
+ private CoapClient rdClient = null;
+ ///////////
////////// Handler for Account Server
private static final AttributeKey<List<CoapRequest>> keyAccountClient = AttributeKey
}
}
- private CoapClient asClient = new CoapClient();
+ private CoapClient asClient = null;
//////////
private SessionManager sessionManager = null;
- public CoapRelayHandler(SessionManager sessionManager, String rdAddress,
- int rdPort, String acAddress, int acPort) {
+ public CoapRelayHandler(SessionManager sessionManager) {
this.sessionManager = sessionManager;
+ rdClient = new CoapClient();
+
rdClient.addHandler(new RDHandler());
+ asClient = new CoapClient();
+
asClient.addHandler(new AccountHandler());
+ }
- try {
- rdClient.startClient(new InetSocketAddress(rdAddress, rdPort));
- asClient.startClient(new InetSocketAddress(acAddress, acPort));
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+ public void startHandler(String rdAddress, int rdPort, String acAddress,
+ int acPort) throws Exception {
+ rdClient.startClient(new InetSocketAddress(rdAddress, rdPort));
+
+ asClient.startClient(new InetSocketAddress(acAddress, acPort));
asClient.getChannelFuture().channel().attr(keyAccountClient)
.set(new ArrayList<CoapRequest>());
}
+ public void stopHandler() throws Exception {
+ asClient.stopClient();
+
+ rdClient.stopClient();
+ }
+
private static final AttributeKey<ChannelHandlerContext> keyDevice = AttributeKey
.newInstance("deviceCtx");
- private HashMap<String, CoapClient> ciRelayClients = new HashMap<String, CoapClient>();
-
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
String uriPath = request.getUriPath();
CoapRequest accountRequest = null;
String userId, deviceId, authPayload;
- CoapResponse response = null;
+ CoapResponse response;
Logger.d("Request received, URI: " + uriPath);
- switch (uriPath) {
- case Constants.AUTH_URI:
- // This case user wants to logout
- if (request.getUriQuery().endsWith("logout")) {
- ctx.channel().attr(Constants.Attribute_UserId).remove();
- response = new CoapResponse(CoapStatus.DELETED);
- } else {
- response = new CoapResponse(CoapStatus.BAD_REQUEST);
- }
- ctx.writeAndFlush(response);
- break;
-
- case Constants.RD_URI:
- // RD POST means publish device to server
- switch (request.getRequestMethod()) {
- case POST:
- userId = ctx.channel()
- .attr(Constants.Attribute_UserId).get();
- deviceId = request.decodeDeviceId();
- authPayload = String.format(
- "{\"userid\":\"%s\",\"deviceid\":\"%s\"}",
- userId, deviceId);
- accountRequest = new CoapRequest(CoapMethod.POST);
- accountRequest.setUriPath(Constants.ACCOUNT_URI);
- accountRequest.setUriQuery("reqtype=publish");
- accountRequest.setToken(request.getToken());
- accountRequest.setPayload(authPayload.getBytes(StandardCharsets.UTF_8));
-
- // TODO: deviceId must be registered after session
- // granted
- Logger.d("Adding deviceId to session: " + deviceId);
- sessionManager.addSession(deviceId, ctx);
- break;
-
- default:
- Logger.e("Unsupported request type");
- break;
- }
-
- rdClient.getChannelFuture().channel().attr(keyRDClient)
- .set(ctx);
-
- // Add original request to list for future use
- asClient.getChannelFuture().channel().attr(keyAccountClient)
- .get().add(request);
- asClient.sendRequest(accountRequest);
- return;
-
- case Constants.WELL_KNOWN_URI:
- switch (request.getRequestMethod()) {
- case GET:
- userId = ctx.channel()
- .attr(Constants.Attribute_UserId).get();
- authPayload = String.format("{\"userid\":\"%s\"}",
- userId);
- accountRequest = new CoapRequest(CoapMethod.GET);
- accountRequest.setUriPath(Constants.ACCOUNT_URI);
- accountRequest.setUriQuery("reqtype=find");
- accountRequest.setToken(request.getToken());
- accountRequest.setPayload(authPayload.getBytes());
- break;
-
- default:
- Logger.e("Unsupported request type");
- break;
- }
-
- rdClient.getChannelFuture().channel().attr(keyRDClient)
- .set(ctx);
-
- // Add original request to list for future use
- asClient.getChannelFuture().channel().attr(keyAccountClient)
- .get().add(request);
- asClient.sendRequest(accountRequest);
- return;
-
- case Constants.KEEP_ALIVE_URI:
- break;
-
- default:
- List<String> uriPathList = request.getUriPathSegments();
- String originUriPathList = request.getUriPath();
- Logger.i("uriPahtList: " + uriPathList.toString());
- String ciAddress = uriPathList.get(0);
- String did = uriPathList.get(1);
-
- Logger.i("CI address: " + ciAddress);
- Logger.i("did: " + did);
-
- // TODO: getMyIP ?
- String hostAddress = Net.getMyIpAddress().replace("/", "");
- Logger.i("hostAddress : " + hostAddress);
- // if published CI is mine
- if (hostAddress.equals(ciAddress) == true) {
- // find ctx about did, and send msg
- Logger.d("published CI is mine");
- String resource = new String();
- List<String> pathSegments = uriPathList.subList(2,
- uriPathList.size());
- for (String path : pathSegments) {
- resource += "/";
- resource += path;
- }
- Logger.i("resource: " + resource);
- request.setUriPath(resource);
-
- ChannelHandlerContext deviceCtx = sessionManager
- .querySession(did);
- if (deviceCtx != null) {
- deviceCtx.attr(keyDevice).set(ctx);
- deviceCtx.writeAndFlush(request);
- } else {
- Logger.e("deviceCtx is null");
- response = new CoapResponse(CoapStatus.FORBIDDEN);
- response.setToken(request.getToken());
+ if (uriPath != null) {
+ switch (uriPath) {
+ case Constants.AUTH_URI:
+ // This case user wants to logout
+ String uriQuery = request.getUriQuery();
+ if (uriQuery != null) {
+ if (uriQuery.endsWith("logout")) {
+ ctx.channel().attr(Constants.Attribute_UserId)
+ .remove();
+ response = new CoapResponse(CoapStatus.DELETED);
+ } else {
+ response = new CoapResponse(
+ CoapStatus.BAD_REQUEST);
+ }
ctx.writeAndFlush(response);
}
- } else {
- // if CI is not connected, connect and send msg
- CoapClient otherCI = null;
- synchronized (ciRelayClients) {
- otherCI = ciRelayClients.get(ciAddress);
- if (otherCI == null) {
- otherCI = new CoapClient();
- otherCI.startClient(
- new InetSocketAddress(ciAddress, 5683));
- ciRelayClients.put(ciAddress, otherCI);
+ break;
+
+ case Constants.RD_URI:
+ // RD POST means publish device to server
+ switch (request.getRequestMethod()) {
+ case POST:
+ userId = ctx.channel()
+ .attr(Constants.Attribute_UserId).get();
+ deviceId = request.decodeDeviceId();
+ authPayload = String.format(
+ "{\"userid\":\"%s\",\"deviceid\":\"%s\"}",
+ userId, deviceId);
+ accountRequest = new CoapRequest(
+ CoapMethod.POST);
+ accountRequest
+ .setUriPath(Constants.ACCOUNT_URI);
+ accountRequest.setUriQuery("reqtype=publish");
+ accountRequest.setToken(request.getToken());
+ accountRequest.setPayload(authPayload
+ .getBytes(StandardCharsets.UTF_8));
+
+ // TODO: deviceId must be registered after
+ // session
+ // granted
+ Logger.d("Adding deviceId to session: "
+ + deviceId);
+ sessionManager.addSession(deviceId, ctx);
+ break;
+
+ default:
+ Logger.e("Unsupported request type");
+ break;
+ }
+
+ rdClient.getChannelFuture().channel().attr(keyRDClient)
+ .set(ctx);
+
+ // Add original request to list for future use
+ asClient.getChannelFuture().channel()
+ .attr(keyAccountClient).get().add(request);
+ asClient.sendRequest(accountRequest);
+ return;
+
+ case Constants.WELL_KNOWN_URI:
+ switch (request.getRequestMethod()) {
+ case GET:
+ userId = ctx.channel()
+ .attr(Constants.Attribute_UserId).get();
+ authPayload = String
+ .format("{\"userid\":\"%s\"}", userId);
+ accountRequest = new CoapRequest(
+ CoapMethod.GET);
+ accountRequest
+ .setUriPath(Constants.ACCOUNT_URI);
+ accountRequest.setUriQuery("reqtype=find");
+ accountRequest.setToken(request.getToken());
+ accountRequest.setPayload(authPayload
+ .getBytes(StandardCharsets.UTF_8));
+ break;
+
+ default:
+ Logger.e("Unsupported request type");
+ break;
+ }
+
+ rdClient.getChannelFuture().channel().attr(keyRDClient)
+ .set(ctx);
+
+ // Add original request to list for future use
+ asClient.getChannelFuture().channel()
+ .attr(keyAccountClient).get().add(request);
+ asClient.sendRequest(accountRequest);
+ return;
+
+ case Constants.KEEP_ALIVE_URI:
+ break;
+
+ default:
+ List<String> uriPathList = request.getUriPathSegments();
+ if (uriPathList != null) {
+ Logger.i("uriPahtList: " + uriPathList.toString());
+
+ String did = uriPathList.get(0);
+
+ Logger.i("did: " + did);
+
+ // TODO: Clustering algorithm required
+ // find ctx about did, and send msg
+ StringBuffer resource = new StringBuffer();
+ List<String> pathSegments = uriPathList.subList(1,
+ uriPathList.size());
+ for (String path : pathSegments) {
+ resource.append("/");
+ resource.append(path);
+ }
+ Logger.i("resource: " + resource);
+ request.setUriPath(resource.toString());
+
+ ChannelHandlerContext deviceCtx = sessionManager
+ .querySession(did);
+ if (deviceCtx != null) {
+ deviceCtx.attr(keyDevice).set(ctx);
+ deviceCtx.writeAndFlush(request);
+ } else {
+ Logger.e("deviceCtx is null");
+ response = new CoapResponse(
+ CoapStatus.FORBIDDEN);
+ response.setToken(request.getToken());
+ ctx.writeAndFlush(response);
}
}
- request.setUriPath(originUriPathList);
- otherCI.sendRequest(request);
- }
- return;
+ return;
+ }
}
} else if (msg instanceof CoapResponse) {
- if (ctx.attr(keyDevice).get() != null) {
- Logger.i("ctx.channel : "
- + ctx.attr(keyDevice).get().channel().toString());
- ctx.attr(keyDevice).get().writeAndFlush(msg);
+ ChannelHandlerContext resourceClient = ctx.attr(keyDevice).get();
+ if (resourceClient != null) {
+ Logger.i("Forwards message to client");
+
+ CoapResponse response = (CoapResponse) msg;
+
+ // If response contains path, add di
+ String did = sessionManager.queryDid(ctx);
+ if (response.getOption(11) != null && did != null) {
+ response.getOption(11).add(0,
+ did.getBytes(StandardCharsets.UTF_8));
+ }
+
+ Logger.i(
+ "ctx.channel : " + resourceClient.channel().toString());
+ resourceClient.writeAndFlush(response);
return;
}
}
}
@Override
+ public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+ Logger.d("Channel Inactive");
+ sessionManager.removeSessionByChannel(ctx);
+ super.channelInactive(ctx);
+ }
+
+ @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
this.sessionManager = sessionManager;
connectPool = new HashMap<ChannelHandlerContext, Long>();
timer = new Timer();
- timer.schedule(new KeepAliveTask(), 30000, 60000);
cbor = new Cbor<HashMap<String, Integer>>();
}
+ public void startSessionChecker() {
+ timer.schedule(new KeepAliveTask(), 30000, 60000);
+ }
+
+ public void stopSessionChecker() {
+ timer.cancel();
+ }
+
/**
* API for receiving message(message to keepalive resource)
- *
+ *
* @param ctx
* ChannelHandlerContext of request message
* @param request
case PUT:
HashMap<String, Integer> payloadData = null;
payloadData = cbor.parsePayloadFromCbor(request.getPayload(),
- new HashMap<String, Integer>().getClass());
+ HashMap.class);
Logger.d("Receive payloadData : " + payloadData);
- Logger.d("interval : " + payloadData.get("in"));
-
- connectPool.put(ctx, System.currentTimeMillis()
- + (payloadData.get("in") * (long) 60000));
+ if (payloadData != null) {
+ if (payloadData.containsKey("in")) {
+ Logger.d("interval : " + payloadData.get("in"));
+ connectPool.put(ctx, System.currentTimeMillis()
+ + (payloadData.get("in") * (long) 60000));
+ }
+ }
response = makeResponse(request);
break;
/**
* API for making response to Resource
- *
+ *
* @param request
* ChannelHandlerContext of request message
*/
/**
* API for making interval and first response to Resource
- *
+ *
* @param request
* ChannelHandlerContext of request message
*/
// check interval
while (iterator.hasNext()) {
ChannelHandlerContext key = iterator.next();
- Long lifeTime = (Long) map.get(key);
- Logger.d("KeepAliveTask Operating : "
- + key.channel().toString() + ", Time : "
- + (lifeTime - currentTime));
- if (lifeTime < currentTime) {
- deleteList.add(key);
+ if (map.containsKey(key)) {
+ if (map.get(key) != null) {
+ Long lifeTime = (Long) map.get(key);
+ if (lifeTime != null) {
+ Logger.d("KeepAliveTask Operating : "
+ + key.channel().toString() + ", Time : "
+ + (lifeTime - currentTime));
+ if (lifeTime < currentTime) {
+ deleteList.add(key);
+ }
+ }
+ }
}
}
--- /dev/null
+package org.iotivity.cloud.ciserver.testci;
+
+import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+
+import org.iotivity.cloud.base.CoapClient;
+import org.iotivity.cloud.base.CoapServer;
+import org.iotivity.cloud.base.ResourceManager;
+import org.iotivity.cloud.base.SessionManager;
+import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.base.protocols.coap.CoapResponse;
+import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
+import org.iotivity.cloud.ciserver.Constants;
+import org.iotivity.cloud.ciserver.protocols.CoapAuthHandler;
+import org.iotivity.cloud.ciserver.protocols.CoapRelayHandler;
+import org.iotivity.cloud.ciserver.resources.KeepAliveResource;
+import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.CoapLogHandler;
+import org.junit.Test;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+public class TestCloudInterface {
+
+ private SessionManager sessionManager = new SessionManager();
+ private ResourceManager resourceManager = new ResourceManager();
+
+ private CoapServer coapServer = null;
+ private CoapClient coapClient = null;
+ private CoapRelayHandler coapRelayHandler = new CoapRelayHandler(
+ sessionManager);
+ private KeepAliveResource keepAliveResource = new KeepAliveResource(
+ sessionManager, new int[] { 1, 2, 4, 8 });
+
+ static class CoapClientHandler
+ extends SimpleChannelInboundHandler<CoapResponse> {
+
+ ChannelHandlerContext connectCtx = null;
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ connectCtx = ctx;
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext arg0,
+ CoapResponse arg1) throws Exception {
+ // TODO : receive response
+ System.out.println("Get Response");
+ }
+ }
+
+ public void startServer() throws Exception {
+
+ coapServer = new CoapServer();
+
+ coapServer.addHandler(new CoapLogHandler());
+ coapServer.addHandler(coapRelayHandler);
+
+ coapServer.addHandler(resourceManager);
+ resourceManager.registerResource(keepAliveResource);
+
+ coapServer.startServer(new InetSocketAddress(5683));
+ }
+
+ public ChannelHandlerContext startClient() throws Exception {
+
+ coapClient = new CoapClient();
+
+ CoapClientHandler coapHandler = new CoapClientHandler();
+ coapClient.addHandler(coapHandler);
+
+ coapClient.addHandler(new CoapAuthHandler());
+
+ coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
+
+ return coapHandler.connectCtx;
+ }
+
+ public CoapRequest makePayload(CoapRequest request) throws Exception {
+ ArrayList<Object> payload = new ArrayList<Object>();
+
+ HashMap<Object, Object> tags = new HashMap<Object, Object>();
+ tags.put("di", "98f7483c-5a31-4161-ba7e-9c13e0d");
+ tags.put("bm", (int) 1);
+ tags.put("ttl", (int) 86400);
+
+ ArrayList<LinkedHashMap<Object, Object>> publishLinks = new ArrayList<LinkedHashMap<Object, Object>>();
+ LinkedHashMap<Object, Object> link = new LinkedHashMap<Object, Object>();
+ link.put("href", "/a/light");
+ ArrayList<String> rt = new ArrayList<String>();
+ ArrayList<String> itf = new ArrayList<String>();
+ ArrayList<String> mt = new ArrayList<String>();
+ rt.add("core.light");
+ link.put("rt", rt);
+
+ itf.add("oic.if.baseline");
+ link.put("if", itf);
+
+ mt.add("application/json");
+ link.put("mt", mt);
+
+ link.put("ins", 1);
+
+ publishLinks.add(link);
+
+ payload.add(tags);
+ payload.add(publishLinks);
+
+ Cbor<ArrayList<Object>> cbor = new Cbor<ArrayList<Object>>();
+
+ request.setPayload(cbor.encodingPayloadToCbor(payload));
+
+ return request;
+ }
+
+ public CoapRequest makeinterval(CoapRequest request) throws Exception {
+
+ HashMap<Object, Object> payload = new HashMap<Object, Object>();
+ payload.put("in", 1);
+
+ Cbor<ArrayList<Object>> cbor = new Cbor<ArrayList<Object>>();
+
+ request.setPayload(cbor.encodingPayloadToCbor(payload));
+
+ return request;
+ }
+
+ @Test
+ public void TestKeepAlivePutInterval() throws Exception {
+
+ CoapRequest request = new CoapRequest(CoapMethod.PUT);
+ request.setUriPath(Constants.KEEP_ALIVE_URI);
+ request.setToken("1234".getBytes(StandardCharsets.UTF_8));
+ makeinterval(request);
+
+ startServer();
+ startClient();
+
+ coapClient.sendRequest(request);
+
+ System.out.println("Waiting for KeepAliveTask..");
+ Thread.sleep(30000);
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void TestKeepAliveGetFirst() throws Exception {
+
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriPath(Constants.KEEP_ALIVE_URI);
+ request.setToken("1234".getBytes(StandardCharsets.UTF_8));
+
+ startServer();
+ startClient();
+
+ coapClient.sendRequest(request);
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void TestDiscoveryDevice() throws Exception {
+
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriPath(Constants.WELL_KNOWN_URI);
+ request.setUriQuery("rt=oic.wk.rdpub");
+ request.setToken("1234".getBytes(StandardCharsets.UTF_8));
+
+ startServer();
+ startClient();
+
+ coapClient.sendRequest(request);
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void TestPublishDevice() throws Exception {
+
+ CoapRequest request = new CoapRequest(CoapMethod.POST);
+ request.setUriPath(Constants.RD_URI);
+ request.setUriQuery("rt=oic.wk.rdpub");
+ request.setToken("1234".getBytes(StandardCharsets.UTF_8));
+ makePayload(request);
+
+ startServer();
+ startClient();
+
+ coapClient.sendRequest(request);
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void TestAuthURI() throws Exception {
+
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriPath(Constants.AUTH_URI);
+ request.setUriQuery("rt=oic.wk.rdpub");
+ request.setToken("1234".getBytes(StandardCharsets.UTF_8));
+ makePayload(request);
+
+ startServer();
+ startClient();
+
+ coapClient.sendRequest(request);
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void TestRequestGetMessageToDeviceCIOwner() throws Exception {
+
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriPath(
+ "/10.113.64.98/98f7483c-5a31-4161-ba7e-9c13e0d/a/light");
+ request.setToken("1234".getBytes(StandardCharsets.UTF_8));
+ makePayload(request);
+
+ startServer();
+ startClient();
+
+ coapClient.sendRequest(request);
+
+ coapServer.stopServer();
+ coapClient.stopClient();
+ }
+
+ @Test
+ public void TestRequestGetMessageToDeviceNotCIOwner() throws Exception {
+
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriPath(
+ "/98f7483c-5a31-4161-ba7e-9c13e0d/a/light");
+ request.setToken("1234".getBytes(StandardCharsets.UTF_8));
+ makePayload(request);
+
+ startServer();
+ startClient();
+
+ coapClient.sendRequest(request);
+
+ coapServer.stopServer();
+ coapClient.stopClient();
+ }
+
+ @Test
+ public void TestRequestPutMessageToDevice() throws Exception {
+
+ CoapRequest request = new CoapRequest(CoapMethod.PUT);
+ request.setUriPath(
+ "/98f7483c-5a31-4161-ba7e-9c13e0d/a/light");
+ request.setToken("1234".getBytes(StandardCharsets.UTF_8));
+ makePayload(request);
+
+ startServer();
+ startClient();
+
+ coapClient.sendRequest(request);
+
+ coapServer.stopServer();
+ coapClient.stopClient();
+ }
+}
3) Build a CloudStack. If you are building first time, then build the stack.
go to "stack" folder in root directory
- $ mvn install
+ $ mvn install -Dmaven.test.skip=true
4) Build a .jar file
- $ mvn install
+ $ mvn install -Dmaven.test.skip=true
- The CloudResourceDirectory-0.0.1-SNAPSHOT.jar file will be placed in the "target" folder
+++ /dev/null
-package org.iotivity.cloud.rdserver;
-
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-public class JSONUtil {
-
- private static ObjectMapper mapper = new ObjectMapper();
-
- public ArrayList<String> parseJSON(byte[] payload, String key) {
-
- if (payload == null)
- return null;
-
- ArrayList<String> value = null;
-
- try {
- @SuppressWarnings("unchecked")
- Map<String, ArrayList<String>> jsonMap = mapper.readValue(payload,
- Map.class);
- value = jsonMap.get(key);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
-
- return value;
- }
-
- public byte[] writeJSON(HashMap<Object, Object> data) throws Exception {
- if (data == null)
- return null;
-
- byte[] json = null;
- try {
- json = mapper.writeValueAsBytes(data);
- } catch (JsonProcessingException e) {
- e.printStackTrace();
- }
-
- if (json == null)
- json = "{}".getBytes(StandardCharsets.UTF_8);
-
- return json;
- }
-}
LinksPayloadFormat linksPayloadFormat = new LinksPayloadFormat();
ArrayList<LinksPayloadFormat> list = new ArrayList<LinksPayloadFormat>();
- publishPayloadFormat
- .setDeviceName(doc.getString(Constants.RS_DEVICE_NAME));
- publishPayloadFormat.setDi(doc.getString(Constants.RS_DEVICE_ID));
- publishPayloadFormat.setBaseUri(doc.getString(Constants.RS_BASE_URI));
- publishPayloadFormat.setBitmap(doc.getInteger(Constants.RS_BITMAP));
- publishPayloadFormat.setPort(doc.getInteger(Constants.RS_HOSTING_PORT));
- publishPayloadFormat.setIns(doc.getInteger(Constants.RS_INS));
- publishPayloadFormat.setRts(doc.getString(Constants.RS_RTS));
- publishPayloadFormat.setDrel(doc.getString(Constants.RS_DREL));
- publishPayloadFormat.setTtl(doc.getInteger(Constants.RS_TTL));
-
- linksPayloadFormat.setHref(doc.getString(Constants.RS_HREF));
- linksPayloadFormat
- .setRt((ArrayList<String>) doc.get(Constants.RS_RESOURCE_TYPE));
- linksPayloadFormat
- .setItf((ArrayList<String>) doc.get(Constants.RS_INTERFACE));
- linksPayloadFormat.setRel(doc.getString(Constants.RS_REL));
- linksPayloadFormat.setObs(doc.getBoolean(Constants.RS_OBS));
- linksPayloadFormat.setTitle(doc.getString(Constants.RS_TITLE));
- linksPayloadFormat.setUri(doc.getString(Constants.RS_URI));
- linksPayloadFormat.setIns(doc.getInteger(Constants.RS_INS));
- linksPayloadFormat
- .setMt((ArrayList<String>) doc.get(Constants.RS_MEDIA_TYPE));
+ Object tmp = null;
+
+ tmp = doc.get(Constants.RS_DEVICE_NAME);
+ if(tmp != null) {
+ publishPayloadFormat
+ .setDeviceName(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_DEVICE_ID);
+ if(tmp != null) {
+ publishPayloadFormat.setDi(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_BASE_URI);
+ if(tmp != null) {
+ publishPayloadFormat.setBaseUri(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_BITMAP);
+ if(tmp != null) {
+ publishPayloadFormat.setBitmap((int)tmp);
+ }
+
+ tmp = doc.get(Constants.RS_HOSTING_PORT);
+ if(tmp != null) {
+ publishPayloadFormat.setPort((int)tmp);
+ }
+
+ tmp = doc.get(Constants.RS_INS);
+ if(tmp != null) {
+ publishPayloadFormat.setIns((int)tmp);
+ }
+
+ tmp = doc.get(Constants.RS_RTS);
+ if(tmp != null) {
+ publishPayloadFormat.setRts(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_DREL);
+ if(tmp != null) {
+ publishPayloadFormat.setDrel(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_TTL);
+ if(tmp != null) {
+ publishPayloadFormat.setTtl((int)tmp);
+ }
+
+ tmp = doc.get(Constants.RS_HREF);
+ if(tmp != null) {
+ linksPayloadFormat.setHref(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_RESOURCE_TYPE);
+ if(tmp != null) {
+ linksPayloadFormat
+ .setRt((ArrayList<String>) tmp);
+ }
+
+ tmp = doc.get(Constants.RS_INTERFACE);
+ if(tmp != null) {
+ linksPayloadFormat
+ .setItf((ArrayList<String>) tmp);
+ }
+
+ tmp = doc.get(Constants.RS_REL);
+ if(tmp != null) {
+ linksPayloadFormat.setRel(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_OBS);
+ if(tmp != null) {
+ linksPayloadFormat.setObs((boolean)tmp);
+ }
+
+ tmp = doc.get(Constants.RS_TITLE);
+ if(tmp != null) {
+ linksPayloadFormat.setTitle(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_URI);
+ if(tmp != null) {
+ linksPayloadFormat.setUri(tmp.toString());
+ }
+
+ tmp = doc.get(Constants.RS_INS);
+ if(tmp != null) {
+ linksPayloadFormat.setIns((int)tmp);
+ }
+
+ tmp = doc.get(Constants.RS_MEDIA_TYPE);
+ if(tmp != null) {
+ linksPayloadFormat
+ .setMt((ArrayList<String>) tmp);
+ }
list.add(linksPayloadFormat);
publishPayloadFormat.setLinks(list);
package org.iotivity.cloud.rdserver;
import java.net.InetSocketAddress;
+import java.util.Scanner;
import org.iotivity.cloud.base.CoapServer;
import org.iotivity.cloud.base.ResourceManager;
import org.iotivity.cloud.rdserver.resources.ResourceDirectoryResource;
import org.iotivity.cloud.util.Logger;
-import org.iotivity.cloud.util.Net;
public class ResourceDirectoryServer {
public static void main(String[] args) throws Exception {
System.out.println("-----RD SERVER-----");
- String hostAddress = Net.getMyIpAddress();
- if (hostAddress.equals("") == true) {
- Logger.e("cannot find host address.");
- return;
- }
if (args.length != 1) {
Logger.e("coap server port required");
coapServer
.startServer(new InetSocketAddress(Integer.parseInt(args[0])));
- }
+ Scanner in = new Scanner(System.in, "UTF-8");
+
+ System.out.println("press 'q' to terminate");
+
+ while (!in.nextLine().equals("q"));
+
+ in.close();
+
+ System.out.println("Terminating...");
+
+ coapServer.stopServer();
+
+ System.out.println("Terminated");
+ }
}
*/
package org.iotivity.cloud.rdserver.resources;
-import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import org.iotivity.cloud.base.protocols.coap.enums.CoapOption;
import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
import org.iotivity.cloud.rdserver.Constants;
-import org.iotivity.cloud.rdserver.JSONUtil;
import org.iotivity.cloud.rdserver.MongoDB;
import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.JSONUtil;
import org.iotivity.cloud.util.Logger;
-import org.iotivity.cloud.util.Net;
import io.netty.channel.ChannelHandlerContext;
for (HashMap<Object, Object> segmentPayload : discoverPayload) {
String stringDi = segmentPayload.get(Constants.RS_DEVICE_ID)
.toString();
- segmentPayload.put(Constants.RS_DEVICE_ID, stringDi.getBytes(StandardCharsets.UTF_8));
+ segmentPayload.put(Constants.RS_DEVICE_ID,
+ stringDi.getBytes(StandardCharsets.UTF_8));
}
Logger.i("discoverPayload :" + discoverPayload.toString());
"st is not null, so this is the get msg about private devices");
// parse payload
byte[] payload = request.getPayload();
- JSONUtil util = new JSONUtil();
- ArrayList<String> deviceList = util.parseJSON(payload,
+ ArrayList<String> deviceList = JSONUtil.parseJSON(payload,
Constants.RS_DEVICE_LIST_KEY);
if (deviceList == null) {
throw new IllegalArgumentException("deviceList is null");
PublishPayloadFormat pubPayload = new PublishPayloadFormat();
- String ciAddress = ((InetSocketAddress) ctx.channel()
- .remoteAddress()).getAddress().getHostAddress();
-
- if (ciAddress.equalsIgnoreCase("127.0.0.1")) {
- ciAddress = Net.getMyIpAddress().replace("/", "");
- }
-
ArrayList<Object> payloadData = cbor.parsePayloadFromCbor(
request.getPayload(), ArrayList.class);
- Logger.i("payloadData: " + payloadData.toString());
+ if (payloadData == null) {
+ throw new IllegalArgumentException("parsed payload is null");
+ } else {
+ Logger.i("payloadData: " + payloadData.toString());
+ }
HashMap<Object, Object> tags = (HashMap<Object, Object>) payloadData
.get(0);
throw new IllegalArgumentException("tags is null!");
}
- if (tags.get(Constants.RS_DEVICE_ID) != null) {
- pubPayload.setDi(tags.get(Constants.RS_DEVICE_ID).toString());
+ Object di = tags.get(Constants.RS_DEVICE_ID);
+ if (di != null) {
+ pubPayload.setDi(di.toString());
Logger.i("di : " + pubPayload.getDi());
} else {
throw new IllegalArgumentException("device id is null!");
}
- if (tags.get(Constants.RS_DEVICE_NAME) != null) {
- pubPayload.setDeviceName(
- tags.get(Constants.RS_DEVICE_NAME).toString());
+ Object deviceName = tags.get(Constants.RS_DEVICE_NAME);
+ if (deviceName != null) {
+ pubPayload.setDeviceName(deviceName.toString());
Logger.i("device name : " + pubPayload.getDeviceName());
}
- if (tags.get(Constants.RS_BASE_URI) != null) {
- pubPayload
- .setBaseUri(tags.get(Constants.RS_BASE_URI).toString());
+ Object baseUri = tags.get(Constants.RS_BASE_URI);
+ if (baseUri != null) {
+ pubPayload.setBaseUri(baseUri.toString());
Logger.i("baseURI : " + pubPayload.getBaseUri());
}
- if (tags.get(Constants.RS_BITMAP) != null) {
- pubPayload.setBitmap((int) tags.get(Constants.RS_BITMAP));
+ Object bitMap = tags.get(Constants.RS_BITMAP);
+ if (bitMap != null) {
+ pubPayload.setBitmap((int) bitMap);
Logger.i("bm : " + pubPayload.getBitmap());
}
- if (tags.get(Constants.RS_HOSTING_PORT) != null) {
- pubPayload.setPort((int) tags.get(Constants.RS_HOSTING_PORT));
+ Object hostingPort = tags.get(Constants.RS_HOSTING_PORT);
+ if (hostingPort != null) {
+ pubPayload.setPort((int) hostingPort);
Logger.i("port : " + pubPayload.getPort());
}
- if (tags.get(Constants.RS_INS) != null) {
- pubPayload.setIns((int) tags.get(Constants.RS_INS));
+ Object ins = tags.get(Constants.RS_INS);
+ if (ins != null) {
+ pubPayload.setIns((int) ins);
Logger.i("ins : " + pubPayload.getIns());
}
- if (tags.get(Constants.RS_RTS) != null) {
- pubPayload.setRts(tags.get(Constants.RS_RTS).toString());
+ Object rts = tags.get(Constants.RS_RTS);
+ if (rts != null) {
+ pubPayload.setRts(rts.toString());
Logger.i("rts : " + pubPayload.getRts());
}
- if (tags.get(Constants.RS_DREL) != null) {
- pubPayload.setDrel(tags.get(Constants.RS_DREL).toString());
+ Object drel = tags.get(Constants.RS_DREL);
+ if (drel != null) {
+ pubPayload.setDrel(drel.toString());
Logger.i("drel : " + pubPayload.getDrel());
}
- if (tags.get(Constants.RS_TTL) != null) {
- pubPayload.setTtl((int) tags.get(Constants.RS_TTL));
- Logger.i("ttl : " + pubPayload.getTtl());
- }
+ // Object ttl = tags.get(Constants.RS_TTL);
+ // if (ttl != null) {
+ // pubPayload.setTtl((int) ttl);
+ // Logger.i("ttl : " + pubPayload.getTtl());
+ // }
ArrayList<LinkedHashMap<Object, Object>> publishLinks = (ArrayList<LinkedHashMap<Object, Object>>) payloadData
.get(1);
LinksPayloadFormat storeLinks = new LinksPayloadFormat();
- if (o.get(Constants.RS_HREF) != null) {
- String prefix = "/" + ciAddress + "/" + pubPayload.getDi();
- storeLinks.setHref(
- prefix + o.get(Constants.RS_HREF).toString());
+ Object href = o.get(Constants.RS_HREF);
+ if (href != null) {
+ String prefix = "/" + pubPayload.getDi();
+ storeLinks.setHref(prefix + href.toString());
Logger.i("href : " + storeLinks.getHref());
}
if (o.get(Constants.RS_RESOURCE_TYPE) != null) {
- storeLinks.setRt((ArrayList<String>) o
- .get(Constants.RS_RESOURCE_TYPE));
- Logger.i("rt : " + storeLinks.getRt().toString());
+ Object obj = o.get(Constants.RS_RESOURCE_TYPE);
+ if (obj != null) {
+ storeLinks.setRt((ArrayList<String>) obj);
+ }
+ Object rt = storeLinks.getRt();
+ if (rt != null) {
+ Logger.i("rt : " + storeLinks.getRt().toString());
+ }
}
if (o.get(Constants.RS_INTERFACE) != null) {
storeLinks.setItf(
(ArrayList<String>) o.get(Constants.RS_INTERFACE));
- Logger.i("if : " + storeLinks.getItf().toString());
+ Object itf = storeLinks.getItf();
+ if (itf != null) {
+ Logger.i("if : " + storeLinks.getItf().toString());
+ }
}
- if (o.get(Constants.RS_REL) != null) {
- storeLinks.setRel(o.get(Constants.RS_REL).toString());
+ Object rel = o.get(Constants.RS_REL);
+ if (rel != null) {
+ storeLinks.setRel(rel.toString());
Logger.i("rel : " + storeLinks.getRel());
}
if (o.get(Constants.RS_OBS) != null) {
- storeLinks.setObs((boolean) o.get(Constants.RS_OBS));
+ Object obj = o.get(Constants.RS_OBS);
+ if (obj != null) {
+ storeLinks.setObs((boolean) obj);
+ }
Logger.i("obs : " + storeLinks.isObs());
}
if (o.get(Constants.RS_TITLE) != null) {
- storeLinks.setTitle(o.get(Constants.RS_TITLE).toString());
+ Object obj = o.get(Constants.RS_TITLE);
+ if (obj != null) {
+ storeLinks.setTitle(obj.toString());
+ }
Logger.i("title : " + storeLinks.getTitle());
}
if (o.get(Constants.RS_URI) != null) {
- storeLinks.setUri(o.get(Constants.RS_URI).toString());
+ Object obj = o.get(Constants.RS_URI);
+ if (obj != null) {
+ storeLinks.setUri(obj.toString());
+ }
Logger.i("uri : " + storeLinks.getUri());
}
if (o.get(Constants.RS_INS) != null) {
- storeLinks.setIns((int) (o.get(Constants.RS_INS)));
+ Object obj = o.get(Constants.RS_INS);
+ if (obj != null) {
+ storeLinks.setIns((int) obj);
+ }
Logger.i("ins : " + storeLinks.getIns());
}
if (o.get(Constants.RS_MEDIA_TYPE) != null) {
- storeLinks.setMt(
- (ArrayList<String>) o.get(Constants.RS_MEDIA_TYPE));
- Logger.i("mt : " + storeLinks.getMt().toString());
+ Object obj = o.get(Constants.RS_MEDIA_TYPE);
+ if (obj != null) {
+ storeLinks.setMt((ArrayList<String>) obj);
+ }
+ Object mt = storeLinks.getMt();
+ if (mt != null) {
+ Logger.i("mt : " + mt.toString());
+ }
}
pubPayload.links.add(storeLinks);
import org.iotivity.cloud.base.protocols.coap.CoapResponse;
import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
import org.iotivity.cloud.rdserver.Constants;
-import org.iotivity.cloud.rdserver.JSONUtil;
import org.iotivity.cloud.rdserver.resources.ResourceDirectoryResource;
import org.iotivity.cloud.util.Cbor;
+import org.iotivity.cloud.util.JSONUtil;
import org.junit.Test;
import io.netty.channel.ChannelHandlerContext;
CoapClientHandler coapHandler = new CoapClientHandler();
coapClient.addHandler(coapHandler);
coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
+ if (coapHandler.connectCtx == null) {
+ throw new IllegalArgumentException("connectCtx is null");
+ }
return coapHandler.connectCtx;
}
CoapRequest request = new CoapRequest(CoapMethod.POST);
request.setUriPath(Constants.RD_URI);
- request.setUriQuery("rt=oic.wk.rdPub");
+ request.setUriQuery("rt=oic.wk.rdpub");
request.setToken("1234".getBytes(StandardCharsets.UTF_8));
ArrayList<Object> payload = new ArrayList<Object>();
ArrayList<String> didList = new ArrayList<String>();
didList.add("98f7483c-5a31-4161-ba7e-9c13e0d");
data.put("devices", didList);
- JSONUtil util = new JSONUtil();
- byte[] payload = util.writeJSON(data);
- request.setPayload(payload);
+ String payload = JSONUtil.writeJSON(data);
+ if (payload != null) {
+ request.setPayload(payload.getBytes(StandardCharsets.UTF_8));
+ }
+ else {
+ throw new IllegalArgumentException("payload writeJson error");
+ }
startServer();
ChannelHandlerContext ctx = startClient();
cc_sample_app_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x', '-pthread'])
cc_sample_app_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
cc_sample_app_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
-cc_sample_app_env.PrependUnique(LIBS = ['oc', 'octbstack'])
+cc_sample_app_env.PrependUnique(LIBS = ['octbstack', 'pthread'])
######################################################################
# Source files and Targets
'sample_device.cpp',
]
-cc_client = cc_sample_app_env.Program('cloud_device', cc_sample_src)
-cc_sample_app_env.InstallTarget(cc_client, 'cloud_device')
\ No newline at end of file
+cc_client = cc_sample_app_env.Program('cloud_device', cc_sample_src)
\ No newline at end of file
return OC_STACK_OK;
}
-OCStackResult parseHost(const char *host, int *port, char *addr)
-{
- //Parse addr, port from host
- if (strstr(host, DEFAULT_COAP_TCP_HOST) != NULL)
- {
- *port = DEFAULT_COAP_TCP_PORT;
- strncpy(addr, host + strlen(DEFAULT_COAP_TCP_HOST),
- strlen(host) - strlen(DEFAULT_COAP_TCP_HOST));
- }
- else if (strstr(host, DEFAULT_COAP_TCP_SECURE_HOST) != NULL)
- {
- *port = DEFAULT_COAP_TCP_SECURE_PORT;
- strncpy(addr, host + strlen(DEFAULT_COAP_TCP_SECURE_HOST),
- strlen(host) - strlen(DEFAULT_COAP_TCP_SECURE_HOST));
- }
- else
- {
- return OC_STACK_INVALID_URI;
- }
-
- if (strchr(addr, ':') != NULL)
- {
- char *strPort = strchr(addr, ':');
- *port = atoi(strPort + 1);
- addr[strlen(addr) - strlen(strPort)] = '\0';
- }
-
- return OC_STACK_OK;
-}
-
OCStackResult OCCloudRegisterLogin(const char *host, const char *auth_provider,
const char *auth_code, OCClientResponseHandler response)
{
char targetUri[MAX_URI_LENGTH * 2] = { 0, };
snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, DEFAULT_AUTH_REGISTER_LOGIN);
- int port = 0;
- char addr[MAX_ADDR_STR_SIZE] = { 0, };
-
- if (parseHost(host, &port, (char *)&addr) != OC_STACK_OK)
- {
- return OC_STACK_INVALID_URI;
- }
-
- OCDevAddr authAddr;
- memset(&authAddr, 0, sizeof(OCDevAddr));
- OICStrcpy(authAddr.addr, MAX_ADDR_STR_SIZE, addr);
- authAddr.port = port;
-
OCCallbackData cbData;
memset(&cbData, 0, sizeof(OCCallbackData));
cbData.cb = response;
OCRepPayloadSetPropString(registerPayload, "authprovider", auth_provider);
OCRepPayloadSetPropString(registerPayload, "authcode", auth_code);
- return OCDoResource(NULL, OC_REST_POST, targetUri, &authAddr, (OCPayload *)registerPayload,
+ return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)registerPayload,
CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
no_memory:
char targetUri[MAX_URI_LENGTH * 2] = { 0, };
snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query);
- int port = 0;
- char addr[MAX_ADDR_STR_SIZE] = { 0, };
-
- if (parseHost(host, &port, (char *)&addr) != OC_STACK_OK)
- {
- return OC_STACK_INVALID_URI;
- }
-
- OCDevAddr authAddr;
- memset(&authAddr, 0, sizeof(OCDevAddr));
- OICStrcpy(authAddr.addr, MAX_ADDR_STR_SIZE, addr);
- authAddr.port = port;
-
OCCallbackData cbData;
memset(&cbData, 0, sizeof(OCCallbackData));
cbData.cb = response;
OCRepPayloadSetPropString(loginoutPayload, "session", auth_session);
- return OCDoResource(NULL, OC_REST_POST, targetUri, &authAddr, (OCPayload *)loginoutPayload,
+ return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)loginoutPayload,
CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
no_memory:
char targetUri[MAX_URI_LENGTH * 2] = { 0, };
snprintf(targetUri, MAX_URI_LENGTH * 2, "%s%s", host, query);
- int port = 0;
- char addr[MAX_ADDR_STR_SIZE] = { 0, };
-
- if (parseHost(host, &port, (char *)&addr) != OC_STACK_OK)
- {
- return OC_STACK_INVALID_URI;
- }
-
- OCDevAddr rdAddr;
- memset(&rdAddr, 0, sizeof(OCDevAddr));
- OICStrcpy(rdAddr.addr, MAX_ADDR_STR_SIZE, addr);
- rdAddr.port = port;
-
// Gather all resources locally and do publish
OCCallbackData cbData;
memset(&cbData, 0, sizeof(OCCallbackData));
}
}
- if (OC_STACK_OK == OCGetNumberOfResourceTypes(handle, &numElement))
+ if (OC_STACK_OK == OCGetNumberOfResourceInterfaces(handle, &numElement))
{
OCStackResult res = createStringLL(numElement, handle, OCGetResourceInterfaceName, &itf);
if (res != OC_STACK_OK || !itf)
goto no_memory;
}
- return OCDoResource(NULL, OC_REST_POST, targetUri, &rdAddr, (OCPayload *)rdPayload,
+ return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload,
CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
no_memory:
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
///
-/// This sample provides steps to define an interface for a resource
-/// (properties and methods) and host this resource on the server.
-/// Additionally, it'll have a client example to discover it as well.
+/// This sample provides the way to create cloud sample
///
#include <memory>
#include <iostream>
#include <condition_variable>
#include <map>
#include <vector>
-#include "OCPlatform.h"
-#include "OCApi.h"
+#include <string>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "ocstack.h"
+#include "ocpayload.h"
#include "cloud_connector.h"
#define DEFAULT_CONTEXT_VALUE 0x99
#define DEFAULT_PUBLISH_QUERY "/oic/rd?rt=oic.wk.rdpub"
-#define DEFAULT_DISCOVER_QUERY "/oic/res?rt=core.foo"
-
-using namespace OC;
+#define DEFAULT_DISCOVER_QUERY "/oic/res?rt=core.light"
-typedef std::map<OCResourceIdentifier, std::shared_ptr<OCResource>> DiscoveredResourceMap;
+////////////////////////////////////////Device Sample
+#define SAMPLE_MAX_NUM_POST_INSTANCE 2
+typedef struct LIGHTRESOURCE
+{
+ OCResourceHandle handle;
+ bool state;
+ int power;
+} LightResource;
+static LightResource gLightInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
-DiscoveredResourceMap discoveredResources;
-class ResourceClient
+OCRepPayload *responsePayload(int64_t power, bool state)
{
- private:
- void putResourceInfo(const HeaderOptions & /*headerOptions*/,
- const OCRepresentation rep, const OCRepresentation /*rep2*/, const int eCode)
- {
- std::cout << "In PutResourceInfo" << std::endl;
-
- std::cout << "Clientside Put response to get was: " << std::endl;
- std::cout << "ErrorCode: " << eCode << std::endl;
+ OCRepPayload *payload = OCRepPayloadCreate();
+ if (!payload)
+ {
+ std::cout << "Failed to allocate Payload" << std::endl;
+ return nullptr;
+ }
- if (eCode == 0)
- {
- std::cout << "Successful Put. Attributes sent were: " << std::endl;
+ OCRepPayloadSetPropBool(payload, "state", state);
+ OCRepPayloadSetPropInt(payload, "power", power);
- rep.getValue("isFoo", m_isFoo);
- rep.getValue("barCount", m_barCount);
+ return payload;
+}
- std::cout << "\tisFoo: " << m_isFoo << std::endl;
- std::cout << "\tbarCount: " << m_barCount << std::endl;
+OCRepPayload *constructResponse(OCEntityHandlerRequest *ehRequest)
+{
+ if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+ {
+ std::cout << "Incoming payload not a representation" << std::endl;
+ return nullptr;
+ }
- std::cout << "Actual New values are: " << std::endl;
+ LightResource *currLightResource = NULL;
- rep.getValue("isFoo", m_isFoo);
- rep.getValue("barCount", m_barCount);
+ if (ehRequest->resource == gLightInstance[0].handle)
+ {
+ currLightResource = &gLightInstance[0];
+ }
+ else if (ehRequest->resource == gLightInstance[1].handle)
+ {
+ currLightResource = &gLightInstance[1];
+ }
- std::cout << "\tisFoo: " << m_isFoo << std::endl;
- std::cout << "\tbarCount: " << m_barCount << std::endl;
+ if (OC_REST_PUT == ehRequest->method)
+ {
+ // Get pointer to query
+ int64_t pow;
+ OCRepPayload *input = reinterpret_cast<OCRepPayload *>(ehRequest->payload);
- m_cv.notify_all();
- }
+ if (OCRepPayloadGetPropInt(input, "power", &pow))
+ {
+ currLightResource->power = pow;
}
- void getResourceInfo(const HeaderOptions & /*headerOptions*/, const OCRepresentation rep,
- const int eCode)
+ bool state;
+ if (OCRepPayloadGetPropBool(input, "state", &state))
{
- std::cout << "In getResourceInfo" << std::endl;
-
- std::cout << "Clientside response to get was: " << std::endl;
- std::cout << "Error Code: " << eCode << std::endl;
-
- if (eCode == 0)
- {
- std::cout << "Successful Get. Attributes are: " << std::endl;
-
- rep.getValue("isFoo", m_isFoo);
- rep.getValue("barCount", m_barCount);
+ currLightResource->state = state;
+ }
+ }
- std::cout << "\tisFoo: " << m_isFoo << std::endl;
- std::cout << "\tbarCount: " << m_barCount << std::endl;
+ return responsePayload(currLightResource->power, currLightResource->state);
+}
- std::cout << "Doing a put on q/foo" << std::endl;
- OCRepresentation rep2(rep);
- m_isFoo = false;
- m_barCount = 211;
+OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest,
+ OCRepPayload **payload)
+{
+ OCRepPayload *getResp = constructResponse(ehRequest);
+ if (!getResp)
+ {
+ std::cout << "constructResponse failed" << std::endl;
+ return OC_EH_ERROR;
+ }
- rep2.setValue("isFoo", m_isFoo);
- rep2.setValue("barCount", m_barCount);
+ *payload = getResp;
- m_resource->put(rep2, QueryParamsMap(),
- PutCallback(std::bind(&ResourceClient::putResourceInfo, this, std::placeholders::_1,
- rep2, std::placeholders::_2, std::placeholders::_3)));
- }
- }
+ return OC_EH_OK;
+}
- void foundResource(std::shared_ptr<OCResource> resource)
- {
- std::cout << "In foundResource" << std::endl;
- std::lock_guard<std::mutex> lock(m_resourceLock);
+OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest,
+ OCRepPayload **payload)
+{
+ OCEntityHandlerResult ehResult;
+ OCRepPayload *putResp = constructResponse(ehRequest);
- if (discoveredResources.find(resource->uniqueIdentifier()) == discoveredResources.end())
- {
- std::cout << "Found resource " << resource->uniqueIdentifier() <<
- " for the first time on server with ID: " << resource->sid() << std::endl;
- discoveredResources[resource->uniqueIdentifier()] = resource;
- }
- else
- {
- std::cout << "Found resource " << resource->uniqueIdentifier() << " again!" << std::endl;
- }
+ if (!putResp)
+ {
+ std::cout << "Failed to construct Json response" << std::endl;
+ return OC_EH_ERROR;
+ }
- if (resource)
- {
- std::cout << "Found Resource: " << std::endl;
- std::cout << "\tHost: " << resource->host() << std::endl;
- std::cout << "\tURI: " << resource->uri() << std::endl;
+ *payload = putResp;
+ ehResult = OC_EH_OK;
- // Get the resource types
- std::cout << "\tList of resource types: " << std::endl;
- for (auto &resourceTypes : resource->getResourceTypes())
- {
- std::cout << "\t\t" << resourceTypes << std::endl;
- }
+ return ehResult;
+}
- // Get the resource interfaces
- std::cout << "\tList of resource interfaces: " << std::endl;
- for (auto &resourceInterfaces : resource->getResourceInterfaces())
- {
- std::cout << "\t\t" << resourceInterfaces << std::endl;
- }
+#define SAMPLE_MAX_NUM_OBSERVATIONS 2
+static bool observeThreadStarted = false;
+int gLightUnderObservation = 0;
+pthread_t threadId_observe;
+typedef struct
+{
+ OCObservationId observationId;
+ bool valid;
+ OCResourceHandle resourceHandle;
+} Observers;
+Observers interestedObservers[SAMPLE_MAX_NUM_OBSERVATIONS];
- std::cout << "found resource OUT" << std::endl;
+void *ChangeLightRepresentation(void *param)
+{
+ (void)param;
+ OCStackResult result = OC_STACK_ERROR;
- m_resource = resource;
+ while (true)
+ {
+ sleep(3);
+ gLightInstance[0].power += 1;
+ gLightInstance[1].power += 3;
- std::cout << "Doing a get on q/foo." << std::endl;
+ if (gLightUnderObservation)
+ {
+ std::cout << " =====> Notifying stack of new power level " << gLightInstance[0].power << std::endl;
+ std::cout << " =====> Notifying stack of new power level " << gLightInstance[1].power << std::endl;
+ // Notifying all observers
+ result = OCNotifyAllObservers(gLightInstance[0].handle, OC_NA_QOS);
+ result = OCNotifyAllObservers(gLightInstance[1].handle, OC_NA_QOS);
- m_resource->get(QueryParamsMap(),
- GetCallback(std::bind(&ResourceClient::getResourceInfo, this,
- std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
- }
+ std::cout << " =====> Notifying result " << result << std::endl;
}
+ }
+ return NULL;
+}
- public:
- ResourceClient()
- {}
+void ProcessObserveRegister(OCEntityHandlerRequest *ehRequest)
+{
+ std::cout << "Received observation registration request with observation Id " <<
+ ehRequest->obsInfo.obsId << std::endl;
- OCStackResult start(std::string hostUri, std::string requestUri)
+ if (!observeThreadStarted)
+ {
+ pthread_create(&threadId_observe, NULL, ChangeLightRepresentation, (void *)NULL);
+ observeThreadStarted = 1;
+ }
+ for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
+ {
+ if (interestedObservers[i].valid == false)
{
- FindCallback f(std::bind(&ResourceClient::foundResource, this, std::placeholders::_1));
-
- return OCPlatform::findResource(hostUri, requestUri, CT_ADAPTER_TCP, f);
+ interestedObservers[i].observationId = ehRequest->obsInfo.obsId;
+ interestedObservers[i].valid = true;
+ gLightUnderObservation = 1;
+ break;
}
- private:
- std::mutex m_mutex;
- std::mutex m_resourceLock;
- std::condition_variable m_cv;
- std::shared_ptr<OCResource> m_resource;
- bool m_isFoo;
- int m_barCount;
-};
-
-struct FooResource
+ }
+}
+
+void ProcessObserveDeregister(OCEntityHandlerRequest *ehRequest)
{
- bool m_isFoo;
- int m_barCount;
- OCResourceHandle m_resourceHandle;
- OCResourceHandle m_resourceHandle2;
- OCRepresentation m_rep;
+ bool clientStillObserving = false;
- FooResource() : m_isFoo(true), m_barCount(0)
+ std::cout << "Received observation deregistration request for observation Id " <<
+ ehRequest->obsInfo.obsId << std::endl;
+ for (uint8_t i = 0; i < SAMPLE_MAX_NUM_OBSERVATIONS; i++)
{
- m_rep.setValue("isFoo", m_isFoo);
- m_rep.setValue("barCount", m_barCount);
+ if (interestedObservers[i].observationId == ehRequest->obsInfo.obsId)
+ {
+ interestedObservers[i].valid = false;
+ }
+ if (interestedObservers[i].valid == true)
+ {
+ // Even if there is one single client observing we continue notifying entity handler
+ clientStillObserving = true;
+ }
}
+ if (clientStillObserving == false)
+ gLightUnderObservation = 0;
+}
- bool createResource(std::string resourceURI)
+OCEntityHandlerResult
+OCEntityHandlerCb(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *entityHandlerRequest, void * /*callback*/)
+{
+ OCEntityHandlerResult ehResult = OC_EH_OK;
+ OCEntityHandlerResponse response = { 0, 0, OC_EH_ERROR, 0, 0, {}, { 0 }, false };
+
+ // Validate pointer
+ if (!entityHandlerRequest)
{
- std::string resourceTypeName = "core.foo";
- std::string resourceInterface = DEFAULT_INTERFACE;
+ std::cout << "Invalid request pointer" << std::endl;
+ return OC_EH_ERROR;
+ }
- m_rep.setUri(resourceURI);
+ // Initialize certain response fields
+ response.numSendVendorSpecificHeaderOptions = 0;
+ memset(response.sendVendorSpecificHeaderOptions,
+ 0, sizeof response.sendVendorSpecificHeaderOptions);
+ memset(response.resourceUri, 0, sizeof response.resourceUri);
+ OCRepPayload *payload = nullptr;
- uint8_t resourceProperty = OC_DISCOVERABLE;
+ if (flag & OC_REQUEST_FLAG)
+ {
+ std::cout << "Flag includes OC_REQUEST_FLAG" << std::endl;
- EntityHandler eh(std::bind(&FooResource::entityHandler,
- this, std::placeholders::_1));
- OCStackResult result = OCPlatform::registerResource(m_resourceHandle,
- resourceURI, resourceTypeName,
- resourceInterface,
- eh, resourceProperty);
- if (OC_STACK_OK != result)
+ if (OC_REST_GET == entityHandlerRequest->method)
+ {
+ std::cout << "Received OC_REST_GET from client" << std::endl;
+ ehResult = ProcessGetRequest(entityHandlerRequest, &payload);
+ }
+ else if (OC_REST_PUT == entityHandlerRequest->method)
+ {
+ std::cout << "Received OC_REST_PUT from client" << std::endl;
+ ehResult = ProcessPutRequest(entityHandlerRequest, &payload);
+ }
+ else
+ {
+ std::cout << "Received unsupported method %d from client " << entityHandlerRequest->method <<
+ std::endl;
+ ehResult = OC_EH_ERROR;
+ }
+ // If the result isn't an error or forbidden, send response
+ if (!((ehResult == OC_EH_ERROR) || (ehResult == OC_EH_FORBIDDEN)))
{
- std::cout << "Resource creation unsuccessful" << std::endl;
- return false;
+ // Format the response. Note this requires some info about the request
+ response.requestHandle = entityHandlerRequest->requestHandle;
+ response.resourceHandle = entityHandlerRequest->resource;
+ response.ehResult = ehResult;
+ response.payload = reinterpret_cast<OCPayload *>(payload);
+ // Indicate that response is NOT in a persistent buffer
+ response.persistentBufferFlag = 0;
+
+ // Send the response
+ if (OCDoResponse(&response) != OC_STACK_OK)
+ {
+ std::cout << "Error sending response" << std::endl;
+ ehResult = OC_EH_ERROR;
+ }
}
+ }
- return true;
+ if (flag & OC_OBSERVE_FLAG)
+ {
+ std::cout << "Flag includes OC_OBSERVE_FLAG" << std::endl;
+ if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
+ {
+ std::cout << "Received OC_OBSERVE_REGISTER from client" << std::endl;
+ ProcessObserveRegister(entityHandlerRequest);
+ }
+ else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
+ {
+ std::cout << "Received OC_OBSERVE_DEREGISTER from client" << std::endl;
+ ProcessObserveDeregister(entityHandlerRequest);
+ }
}
- OCResourceHandle getHandle()
+ OCPayloadDestroy(response.payload);
+ return ehResult;
+}
+
+int createLightResource(char *uri, LightResource *lightResource)
+{
+ if (!uri)
{
- return m_resourceHandle;
+ std::cout << "Resource URI cannot be NULL" << std::endl;
+ return -1;
}
- OCResourceHandle getHandle2()
+ lightResource->state = false;
+ lightResource->power = 0;
+ OCStackResult res = OCCreateResource(&(lightResource->handle),
+ "core.light",
+ "oc.mi.def",
+ uri,
+ OCEntityHandlerCb,
+ NULL,
+ OC_DISCOVERABLE | OC_OBSERVABLE);
+ std::cout << "Created Light resource with result:" << res << std::endl;
+
+ return res;
+}
+
+OCStackApplicationResult handlePublishCB(void *ctx,
+ OCDoHandle /*handle*/,
+ OCClientResponse *clientResponse)
+{
+ if (ctx != (void *)DEFAULT_CONTEXT_VALUE)
{
- return m_resourceHandle2;
+ std::cout << "Invalid Publish callback received" << std::endl;
}
+ std::cout << "Publish resource response received, code: " << clientResponse->result << std::endl;
+
+ return OC_STACK_KEEP_TRANSACTION;
+}
+
+void PublishResources(std::string host, std::string additionalQuery)
+{
+ std::cout << "Running as Server mode" << std::endl;
- OCRepresentation get()
+ std::string requestQuery = DEFAULT_PUBLISH_QUERY;
+ requestQuery += additionalQuery;
+
+ std::cout << "Publishing resources..." << std::endl;
+ std::cout << host.c_str() << requestQuery.c_str() << std::endl;
+
+ if (createLightResource((char *)"/a/light/0", &gLightInstance[0]) != 0)
{
- m_rep.setValue("isFoo", m_isFoo);
- m_rep.setValue("barCount", m_barCount);
+ std::cout << "Unable to create sample resource" << std::endl;
+ }
- return m_rep;
+ if (createLightResource((char *)"/a/light/1", &gLightInstance[1]) != 0)
+ {
+ std::cout << "Unable to create sample resource" << std::endl;
}
- void put(OCRepresentation &rep)
+ if (OCCloudPublish(host.c_str(), requestQuery.c_str(), &handlePublishCB, 2,
+ gLightInstance[0].handle, gLightInstance[1].handle) != OC_STACK_OK)
{
- rep.getValue("isFoo", m_isFoo);
- rep.getValue("barCount", m_barCount);
+ std::cout << "Unable to publish resources to cloud" << std::endl;
}
+}
- OCStackResult sendResponse(std::shared_ptr<OCResourceRequest> pRequest)
+////////////////////////////////////////Client Sample
+std::string g_host = "coap+tcp://";
+
+void PrintRepresentation(OCRepPayloadValue *val)
+{
+ while (val)
{
- auto pResponse = std::make_shared<OC::OCResourceResponse>();
- pResponse->setRequestHandle(pRequest->getRequestHandle());
- pResponse->setResourceHandle(pRequest->getResourceHandle());
- pResponse->setResourceRepresentation(get(), "");
- pResponse->setErrorCode(200);
- pResponse->setResponseResult(OC_EH_OK);
+ std::cout << "Key: " << val->name << " Value: ";
+ switch (val->type)
+ {
+ case OCREP_PROP_NULL:
+ std::cout << "NULL" << std::endl;
+ break;
+
+ case OCREP_PROP_INT:
+ std::cout << val->i << std::endl;
+ break;
+
+ case OCREP_PROP_DOUBLE:
+ std::cout << val->d << std::endl;
+ break;
+
+ case OCREP_PROP_BOOL:
+ std::cout << val->b << std::endl;
+ break;
+
+ case OCREP_PROP_STRING:
+ std::cout << val->str << std::endl;
+ break;
- return OCPlatform::sendResponse(pResponse);
+ case OCREP_PROP_BYTE_STRING:
+ std::cout << "[ByteString]" << std::endl;
+ break;
+
+ case OCREP_PROP_OBJECT:
+ std::cout << "[Object]" << std::endl;
+ break;
+
+ case OCREP_PROP_ARRAY:
+ std::cout << "[Array]" << std::endl;
+ break;
+ }
+
+ val = val->next;
}
+}
+
- OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
+int gNumObserveNotifies = 0;
+
+OCStackApplicationResult obsReqCB(void *ctx, OCDoHandle handle,
+ OCClientResponse *clientResponse)
+{
+ std::cout << "Observe response received from " << clientResponse->resourceUri << std::endl;
+
+ if (ctx != (void *)DEFAULT_CONTEXT_VALUE)
{
- std::cout << "\tConsumer Entity Handler:" << std::endl;
- OCEntityHandlerResult ehResult = OC_EH_ERROR;
+ std::cout << "Invalid Put callback received" << std::endl;
+ }
- if (request)
+ if (clientResponse)
+ {
+ if (clientResponse->payload == NULL)
{
- // Note: Most of the handlers are not here, since this is for
- // demoing client/server co-process existence.
- // See simpleserver for a more complete example.
- if (request->getRequestHandlerFlag() == RequestHandlerFlag::RequestFlag)
- {
- std::cout << "\t\trequestFlag : Request" << std::endl;
-
- if (request->getRequestType() == "GET")
- {
- std::cout << "\t\t\trequestType : GET" << std::endl;
- if (OC_STACK_OK == sendResponse(request))
- {
- ehResult = OC_EH_OK;
- }
- }
- else if (request->getRequestType() == "PUT")
- {
- std::cout << "\t\t\trequestType : PUT" << std::endl;
-
- OCRepresentation rep = request->getResourceRepresentation();
- put(rep);
- if (OC_STACK_OK == sendResponse(request))
- {
- ehResult = OC_EH_OK;
- }
- }
- else
- {
- std::cout << "\t\t\trequestType : UNSUPPORTED: " <<
- request->getRequestType() << std::endl;
- }
- }
- else
- {
- std::cout << "\t\trequestFlag : UNSUPPORTED: ";
+ std::cout << "No payload received" << std::endl;
+ }
+
+ OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;
+
+ PrintRepresentation(val);
- if (request->getRequestHandlerFlag() == RequestHandlerFlag::ObserverFlag)
- {
- std::cout << "ObserverFlag" << std::endl;
- }
+ gNumObserveNotifies++;
+ if (gNumObserveNotifies > 5) //large number to test observing in DELETE case.
+ {
+ std::cout << "Cancelling with OC_HIGH_QOS" << std::endl;
+ if (OCCancel(handle, OC_HIGH_QOS, NULL, 0) != OC_STACK_OK)
+ {
+ std::cout << "Observe cancel error" << std::endl;
}
}
- else
+ if (clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)
{
- std::cout << "Request Invalid!" << std::endl;
+ std::cout << "This also serves as a registration confirmation" << std::endl;
+ }
+ else if (clientResponse->sequenceNumber == OC_OBSERVE_DEREGISTER)
+ {
+ std::cout << "This also serves as a deregistration confirmation" << std::endl;
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ else if (clientResponse->sequenceNumber == OC_OBSERVE_NO_OPTION)
+ {
+ std::cout << "This also tells you that registration/deregistration failed" << std::endl;
+ return OC_STACK_DELETE_TRANSACTION;
}
-
- return ehResult;
}
-};
+ else
+ {
+ std::cout << "obsReqCB received Null clientResponse" << std::endl;
+ }
-OCStackApplicationResult handlePublishCB(void *ctx,
- OCDoHandle /*handle*/,
- OCClientResponse *clientResponse)
+ return OC_STACK_KEEP_TRANSACTION;
+}
+
+void ObserveResource(std::string uri, std::string additionalQuery)
+{
+ OCCallbackData cbData;
+ cbData.cb = obsReqCB;
+ cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ uri += additionalQuery;
+
+ std::cout << "Request OBSERVE to resource " << uri.c_str() << std::endl;
+
+ OCStackResult res = OCDoResource(NULL, OC_REST_OBSERVE, uri.c_str(), NULL, NULL,
+ CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+ std::cout << "Requesting OBSERVE res=" << res << std::endl;
+}
+
+OCStackApplicationResult putReqCB(void *ctx, OCDoHandle /*handle*/,
+ OCClientResponse *clientResponse)
{
+ std::cout << "Put response received from " << clientResponse->resourceUri << std::endl;
+
if (ctx != (void *)DEFAULT_CONTEXT_VALUE)
{
- std::cout << "Invalid Publish callback received" << std::endl;
+ std::cout << "Invalid Put callback received" << std::endl;
}
- std::cout << "Publish resource response received, code: " << clientResponse->result << std::endl;
+ if (clientResponse->payload == NULL)
+ {
+ std::cout << "No payload received" << std::endl;
+ }
+
+ OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;
+
+ PrintRepresentation(val);
+
+ std::string requestUri = g_host;
+ requestUri += clientResponse->resourceUri;
+
+ ObserveResource(requestUri, "");
return OC_STACK_KEEP_TRANSACTION;
}
-OCStackApplicationResult handleLoginoutCB(void *ctx,
- OCDoHandle /*handle*/,
- OCClientResponse *clientResponse)
+OCPayload *putRequestPayload()
+{
+ OCRepPayload *payload = OCRepPayloadCreate();
+
+ if (!payload)
+ {
+ std::cout << "Failed to create put payload object" << std::endl;
+ std::exit(1);
+ }
+
+ OCRepPayloadSetPropInt(payload, "power", 15);
+ OCRepPayloadSetPropBool(payload, "state", true);
+
+ return (OCPayload *)payload;
+}
+
+void PutResource(std::string uri, std::string additionalQuery)
{
+ OCCallbackData cbData;
+ cbData.cb = putReqCB;
+ cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ uri += additionalQuery;
+
+ std::cout << "Request PUT to resource " << uri.c_str() << std::endl;
+
+ OCStackResult res = OCDoResource(NULL, OC_REST_PUT, uri.c_str(), NULL, putRequestPayload(),
+ CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+ std::cout << "Requesting PUT res=" << res << std::endl;
+}
+
+OCStackApplicationResult handleGetCB(void *ctx,
+ OCDoHandle /*handle*/,
+ OCClientResponse *clientResponse)
+{
+ std::cout << "Get response received from " << clientResponse->resourceUri << std::endl;
+
if (ctx != (void *)DEFAULT_CONTEXT_VALUE)
{
- std::cout << "Invalid Login callback received" << std::endl;
+ std::cout << "Invalid Get callback received" << std::endl;
}
- std::cout << "Login/out response received code: " << clientResponse->result << std::endl;
+ if (clientResponse->payload == NULL)
+ {
+ std::cout << "No payload received" << std::endl;
+ }
if (clientResponse->payload != NULL &&
clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
{
- std::cout << "PAYLOAD_TYPE_REPRESENTATION received" << std::endl;
-
OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;
- while (val)
- {
- std::cout << "Name: " << val->name << " Value: " << val->str << std::endl;
- val = val->next;
- }
+ PrintRepresentation(val);
+
+ std::string requestUri = g_host;
+ requestUri += clientResponse->resourceUri;
+
+ PutResource(requestUri, "");
}
return OC_STACK_KEEP_TRANSACTION;
}
-void PrintUsage()
+void GetResource(std::string uri, std::string additionalQuery)
{
- std::cout << std::endl;
- std::cout << "Usage : cloud_device <addr:port> <session>\n";
- std::cout << "<addr:port>: Cloud Address, \"127.0.0.1:5683\"\n";
- std::cout <<
- "<session>: String value, Provided by response of onboarding scenario\n\tor kind of registration portal\n\n";
- std::cout <<
- "If you want to go API test mode include device registration,\n\tleave blank to <session> fields\n";
- std::cout <<
- "sample: \"cloud_device 127.0.0.1:5683\"\n\t-Enter API testmode\n\n";
- std::cout <<
- "sample: \"cloud_device 127.0.0.1:5683 1234567890123456\"\n\t-Enter API testmode using registered session\n\n";
-}
+ OCCallbackData cbData;
+ cbData.cb = handleGetCB;
+ cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
-void PublishResources(std::string host, std::string additionalQuery)
-{
- std::cout << "Running as Server mode" << std::endl;
+ uri += additionalQuery;
- FooResource fooRes1, fooRes2;
+ std::cout << "Request GET to resource " << uri.c_str() << std::endl;
- if (!fooRes1.createResource("/q/resource_foo1"))
+ OCStackResult res = OCDoResource(NULL, OC_REST_GET, uri.c_str(), NULL, NULL,
+ CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+
+ std::cout << "Requesting GET res=" << res << std::endl;
+}
+
+// This is a function called back when a device is discovered
+OCStackApplicationResult discoveryReqCB(void *ctx, OCDoHandle /*handle*/,
+ OCClientResponse *clientResponse)
+{
+ if (ctx == (void *)DEFAULT_CONTEXT_VALUE)
{
- std::cout << "Unable to create resource" << std::endl;
- return;
+ std::cout << "Callback Context for DISCOVER query recvd successfully" << std::endl;
}
- if (!fooRes2.createResource("/q/resource_foo2"))
+ if (clientResponse)
{
- std::cout << "Unable to create resource" << std::endl;
- return;
- }
+ std::cout << "StackResult: " << clientResponse->result << std::endl;
- std::string requestQuery = DEFAULT_PUBLISH_QUERY;
- requestQuery += additionalQuery;
+ OCDiscoveryPayload *payload = (OCDiscoveryPayload *)clientResponse->payload;
+ if (!payload)
+ {
+ std::cout << "Empty payload" << std::endl;
+ return OC_STACK_DELETE_TRANSACTION;
+ }
- std::cout << "Publishing resources..." << std::endl;
- std::cout << host.c_str() << requestQuery.c_str() << std::endl;
+ OCResourcePayload *resource = (OCResourcePayload *)payload->resources;
+ if (!resource)
+ {
+ std::cout << "No resources in payload" << std::endl;
+ return OC_STACK_DELETE_TRANSACTION;
+ }
- if (OCCloudPublish(host.c_str(), requestQuery.c_str(), &handlePublishCB, 2,
- fooRes1.getHandle(), fooRes2.getHandle()) != OC_STACK_OK)
+ while (resource)
+ {
+ std::cout << "Found Resource " << resource->uri << std::endl;
+
+ std::string requestUri = g_host;
+ requestUri += resource->uri;
+
+ GetResource(requestUri, "");
+
+ resource = resource->next;
+ }
+ }
+ else
{
- std::cout << "Unable to publish resources to cloud" << std::endl;
+ std::cout << "discoveryReqCB received Null clientResponse" << std::endl;
}
+ return OC_STACK_KEEP_TRANSACTION;
}
void DiscoverResources(std::string host, std::string additionalQuery)
{
std::cout << "Running as Client mode" << std::endl;
- ResourceClient client;
- std::string requestQuery = DEFAULT_DISCOVER_QUERY;
+ std::string requestQuery = host;
+ requestQuery += DEFAULT_DISCOVER_QUERY;
requestQuery += additionalQuery;
std::cout << "Finding resources..." << std::endl;
- std::cout << host.c_str() << requestQuery.c_str() << std::endl;
+ std::cout << requestQuery.c_str() << std::endl;
- if (client.start(host.c_str(), requestQuery.c_str()) != OC_STACK_OK)
+ OCCallbackData cbData;
+
+ cbData.cb = discoveryReqCB;
+ cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
+ cbData.cd = NULL;
+
+ if (OCDoResource(NULL, OC_REST_DISCOVER, requestQuery.c_str(), NULL, 0, CT_ADAPTER_TCP,
+ OC_LOW_QOS, &cbData, NULL, 0) != OC_STACK_OK)
{
std::cout << "Unable to find resources from cloud" << std::endl;
}
}
-int main(int argc, char *argv[])
+
+
+/////////////////////////////////////////////Common sample
+
+int g_runningMode = 0;
+
+OCStackApplicationResult handleLoginoutCB(void *ctx,
+ OCDoHandle /*handle*/,
+ OCClientResponse *clientResponse)
{
- std::string host = "coap+tcp://";
+ if (ctx != (void *)DEFAULT_CONTEXT_VALUE)
+ {
+ std::cout << "Invalid Login/out callback received" << std::endl;
+ }
- std::string cmdQuery;
- std::string session;
+ std::cout << "Login/out response received code: " << clientResponse->result << std::endl;
+
+ if (clientResponse->payload != NULL &&
+ clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
+ {
+ std::cout << "PAYLOAD_TYPE_REPRESENTATION received" << std::endl;
+
+ OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;
+
+ while (val)
+ {
+ std::cout << "Key: " << val->name << " Value: " << val->str << std::endl;
+ val = val->next;
+ }
- PlatformConfig cfg
+ if (g_runningMode == 1)
+ {
+ PublishResources(g_host, "");
+ }
+ else if (g_runningMode == 2)
+ {
+ DiscoverResources(g_host, "");
+ }
+
+ }
+
+ return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult handleRegisterCB(void *ctx,
+ OCDoHandle /*handle*/,
+ OCClientResponse *clientResponse)
+{
+ if (ctx != (void *)DEFAULT_CONTEXT_VALUE)
{
- OC::ServiceType::InProc,
- OC::ModeType::Both,
- "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
- 0, // Uses randomly available port
- OC::QualityOfService::LowQos
- };
+ std::cout << "Invalid Register callback received" << std::endl;
+ }
- OCPlatform::Configure(cfg);
- FooResource defaultResource;
- if (!defaultResource.createResource("/q/default"))
+ std::cout << "Register response received code: " << clientResponse->result << std::endl;
+
+ if (clientResponse->payload != NULL &&
+ clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)
{
- std::cout << "Unable to create default resource" << std::endl;
- return -1;
+ std::cout << "PAYLOAD_TYPE_REPRESENTATION received" << std::endl;
+ std::cout << "You can login using received session variable after disconnected or reboot" <<
+ std::endl;
+
+ OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;
+
+ while (val)
+ {
+ std::cout << "Key: " << val->name << " Value: " << val->str << std::endl;
+ val = val->next;
+ }
}
+ return OC_STACK_KEEP_TRANSACTION;
+}
+
+void PrintUsage()
+{
+ std::cout << std::endl;
+ std::cout << "Usage : cloud_device <addr:port> <session> <mode>\n";
+ std::cout << "<addr:port>: Cloud Address, \"127.0.0.1:5683\"\n";
+ std::cout <<
+ "<session>: String value, Provided by response of onboarding scenario\n\tor kind of registration portal\n\n";
+ std::cout <<
+ "<mode>: String value, 's' for publish resource, 'c' for start discovery\n\n";
+ std::cout <<
+ "If you want to get session key using OAuth 2 auth code,\n\tleave blank to <session>, <mode> fields\n";
+ std::cout <<
+ "sample: \"cloud_device 127.0.0.1:5683\"\n\t-OAuth 2 registration mode\n\n";
+ std::cout <<
+ "sample: \"cloud_device 127.0.0.1:5683 1234567890123456 s\"\n\t-Publish resource under registered session\n\n";
+ std::cout <<
+ "sample: \"cloud_device 127.0.0.1:5683 1234567890123456 c\"\n\t-Discover resource under registered session\n\n";
+}
+
+int main(int argc, char *argv[])
+{
+ std::string session;
+
+ std::string authProvider;
+ std::string authCode;
+
+ OCMode stackMode = OC_CLIENT;
+
switch (argc)
{
- case 1:
- PrintUsage();
- return 0;
- break;
-
case 2:
- std::cout <<
- "1. Login to cloud using OAuth2 auth code and auth provider name(AuthCode'OAuth2' required)" <<
- std::endl;
- std::cout << "2. Login to cloud using session(Session required)" << std::endl;
- std::cout << "3. Logout from cloud using session(Session required)" << std::endl;
- std::cout << "s. Running as Resource Server mode" << std::endl;
- std::cout << "c. Running as Resource Client mode" << std::endl;
- std::cout << "exit: q" << std::endl;
- std::cin >> cmdQuery;
+ std::cout << "Put auth provider name(ex: github)" << std::endl;
+ std::cin >> authProvider;
+ std::cout << "Put auth code(provided by auth provider)" << std::endl;
+ std::cin >> authCode;
break;
- case 3:
- cmdQuery = "2";
+ case 4:
session = argv[2];
+ if (strlen(argv[3]) != 1)
+ {
+ std::cout << "OCStack init error" << std::endl;
+ return 0;
+ }
+ if (strcmp(argv[3], "s") == 0)
+ {
+ stackMode = OC_CLIENT_SERVER;
+ g_runningMode = 1;
+ }
+ else if (strcmp(argv[3], "c") == 0)
+ {
+ g_runningMode = 2;
+ }
+ else
+ {
+ std::cout << "Invalid <mode>, 's' or 'c' required" << std::endl;
+ return 0;
+ }
break;
+
+ default:
+ PrintUsage();
+ return 0;
}
- host += argv[1];
+ g_host += argv[1];
- std::cout << "Host " << host.c_str() << std::endl;
+ std::cout << "Host " << g_host.c_str() << std::endl;
- std::string authProvider;
- std::string authCode;
+ if (OCInit(NULL, 0, stackMode) != OC_STACK_OK)
+ {
+ std::cout << "OCStack init error" << std::endl;
+ return 0;
+ }
OCStackResult res = OC_STACK_ERROR;
- while (cmdQuery[0] != 'q')
+ switch (argc)
{
- switch (cmdQuery[0])
- {
- case '1':
- std::cout << "Put auth provider name(ex: github)" << std::endl;
- std::cin >> authProvider;
- std::cout << "Put auth code(provided by auth provider)" << std::endl;
- std::cin >> authCode;
- std::cout << "Login to cloud using " << authProvider << " " << authCode << std::endl;
- res = OCCloudRegisterLogin(host.c_str(), authProvider.c_str(), authCode.c_str(),
- handleLoginoutCB);
- std::cout << "OCCloudRegisterLogin return " << res << std::endl;
- break;
+ case 2:
+ std::cout << "Register account to cloud using " << authProvider << " " << authCode << std::endl;
+ res = OCCloudRegisterLogin(g_host.c_str(), authProvider.c_str(), authCode.c_str(),
+ handleRegisterCB);
+ std::cout << "OCCloudRegisterLogin return " << res << std::endl;
+ break;
- case '2':
- std::cout << "Put session to login" << std::endl;
- if (session.size() == 0)
- std::cin >> session;
- else
- std::cout << session.c_str() << std::endl;
- res = OCCloudLogin(host.c_str(), session.c_str(), handleLoginoutCB);
- std::cout << "OCCloudLogin return " << res << std::endl;
- break;
+ case 4:
+ res = OCCloudLogin(g_host.c_str(), session.c_str(), handleLoginoutCB);
+ std::cout << "OCCloudLogin return " << res << std::endl;
+ break;
- case '3':
- std::cout << "Put session to logout" << std::endl;
- if (session.size() == 0)
- std::cin >> session;
- else
- std::cout << session.c_str() << std::endl;
- res = OCCloudLogout(host.c_str(), session.c_str(), handleLoginoutCB);
- std::cout << "OCCloudLogout return" << res << std::endl;
- break;
+ default:
+ PrintUsage();
+ return 0;
+ }
- case 's':
- PublishResources(host, "");
- break;
+ std::cout << "Waiting response.." << std::endl;
- case 'c':
- DiscoverResources(host, "");
- break;
+ while (true)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ std::cout << "OCProcess process error" << std::endl;
}
- std::cin >> cmdQuery;
+ sleep(1);
+ }
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ std::cout << "OCStop process error" << std::endl;
}
return 0;
-}
+}
\ No newline at end of file
2) Build a .jar file
- $ mvn install
+ $ mvn install -Dmaven.test.skip=true
- The CloudStack-0.0.1-SNAPSHOT.jar file will be placed in the "target" folder.
import org.iotivity.cloud.base.protocols.coap.CoapDecoder;
import org.iotivity.cloud.base.protocols.coap.CoapEncoder;
import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.util.Logger;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
}
}
- private ChannelFuture channelFuture;
+ ChannelFuture channelFuture;
+
+ EventLoopGroup connectorGroup = new NioEventLoopGroup();
CoAPClientInitializer initializer = new CoAPClientInitializer();
public void startClient(final InetSocketAddress inetSocketAddress)
throws InterruptedException {
- // Create bootstrap
-
- EventLoopGroup bossGroup = new NioEventLoopGroup();
- // bossGroup = new
- // EpollEventLoopGroup(Runtime.getRuntime().availableProcessors() * 2);
-
+
try {
Bootstrap b = new Bootstrap();
- b.group(bossGroup);
+ b.group(connectorGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.TCP_NODELAY, true);
b.option(ChannelOption.SO_KEEPALIVE, true);
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
- System.out.println(
+ Logger.d(
"Connection status of TCP CoAP CLIENT : "
+ future.isSuccess());
}
channelFuture.channel().writeAndFlush(request);
}
- /**
- * stop connection
- */
- public void stopClient() {
-
- try {
- if (channelFuture != null) {
- channelFuture.channel().disconnect().sync().addListener(
- new GenericFutureListener<ChannelFuture>() {
-
- public void operationComplete(ChannelFuture future)
- throws Exception {
- System.out.println(
- "DisConnection status of TCP CoAP CLIENT : "
- + future.isSuccess());
- }
- });
- }
- } catch (InterruptedException e1) {
- e1.printStackTrace();
- }
+ public void stopClient() throws Exception {
+ connectorGroup.shutdownGracefully().await();
}
}
import org.iotivity.cloud.base.protocols.coap.CoapDecoder;
import org.iotivity.cloud.base.protocols.coap.CoapEncoder;
+import org.iotivity.cloud.util.Logger;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
}
}
- EventLoopGroup bossGroup = new NioEventLoopGroup(1);
+ EventLoopGroup acceptorGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
CoAPServerInitializer initializer = new CoAPServerInitializer();
-
+
public void addHandler(ChannelHandler handler) {
initializer.addHandler(handler);
}
try {
ServerBootstrap b = new ServerBootstrap();
- b.group(bossGroup, workerGroup);
+ b.group(acceptorGroup, workerGroup);
b.channel(NioServerSocketChannel.class);
b.option(ChannelOption.TCP_NODELAY, true);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.childHandler(initializer);
- ChannelFuture ch = b.bind(inetSocketAddress).sync();
- ch.addListener(new GenericFutureListener<ChannelFuture>() {
+ ChannelFuture channelFuture = b.bind(inetSocketAddress).sync();
+ channelFuture.addListener(new GenericFutureListener<ChannelFuture>() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
// TODO Auto-generated method stub
- System.out
- .println("Connection status of TCP CoAP SERVER : "
+ Logger.d("Connection status of TCP CoAP SERVER : "
+ future.isSuccess());
}
-
});
} finally {
}
-
}
- public void stopServer() {
- // shut down all event loops
- if (bossGroup != null) {
- bossGroup.shutdownGracefully();
-
- try {
- bossGroup.terminationFuture().sync();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- if (workerGroup != null) {
- workerGroup.shutdownGracefully();
-
- try {
- workerGroup.terminationFuture().sync();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
+ public void stopServer() throws Exception {
+ acceptorGroup.shutdownGracefully().await();
+ workerGroup.shutdownGracefully().await();
}
-
}
*
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
-package org.iotivity.cloud.base;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-import javax.net.ssl.SSLException;
-
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.handler.codec.http.ClientCookieEncoder;
-import io.netty.handler.codec.http.DefaultCookie;
-import io.netty.handler.codec.http.DefaultFullHttpRequest;
-import io.netty.handler.codec.http.HttpClientCodec;
-import io.netty.handler.codec.http.HttpContent;
-import io.netty.handler.codec.http.HttpContentDecompressor;
-import io.netty.handler.codec.http.HttpHeaders;
-import io.netty.handler.codec.http.HttpMethod;
-import io.netty.handler.codec.http.HttpObject;
-import io.netty.handler.codec.http.HttpRequest;
-import io.netty.handler.codec.http.HttpResponse;
-import io.netty.handler.codec.http.HttpVersion;
-import io.netty.handler.codec.http.LastHttpContent;
-import io.netty.handler.ssl.SslContext;
-import io.netty.handler.ssl.SslContextBuilder;
-import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-import io.netty.util.CharsetUtil;
-
-public class HttpClient {
-
- private static class HttpClientInitializer
- extends ChannelInitializer<SocketChannel> {
-
- public static class HttpSnoopClientHandler
- extends SimpleChannelInboundHandler<HttpObject> {
-
- @Override
- public void channelRead0(ChannelHandlerContext ctx,
- HttpObject msg) {
- if (msg instanceof HttpResponse) {
- HttpResponse response = (HttpResponse) msg;
-
- System.err.println("STATUS: " + response.getStatus());
- System.err.println(
- "VERSION: " + response.getProtocolVersion());
- System.err.println();
-
- if (!response.headers().isEmpty()) {
- for (String name : response.headers().names()) {
- for (String value : response.headers()
- .getAll(name)) {
- System.err.println(
- "HEADER: " + name + " = " + value);
- }
- }
- System.err.println();
- }
-
- if (HttpHeaders.isTransferEncodingChunked(response)) {
- System.err.println("CHUNKED CONTENT {");
- } else {
- System.err.println("CONTENT {");
- }
- }
- if (msg instanceof HttpContent) {
- HttpContent content = (HttpContent) msg;
-
- System.err.print(
- content.content().toString(CharsetUtil.UTF_8));
- System.err.flush();
-
- if (content instanceof LastHttpContent) {
- System.err.println("} END OF CONTENT");
- ctx.close();
- }
- }
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx,
- Throwable cause) {
- cause.printStackTrace();
- ctx.close();
- }
- }
-
- private final SslContext sslCtx;
-
- public HttpClientInitializer(SslContext sslCtx) {
- this.sslCtx = sslCtx;
- }
-
- @Override
- public void initChannel(SocketChannel ch) {
- ChannelPipeline p = ch.pipeline();
-
- // Enable HTTPS if necessary.
- if (sslCtx != null) {
- p.addLast(sslCtx.newHandler(ch.alloc()));
- }
-
- p.addLast(new HttpClientCodec());
-
- // Remove the following line if you don't want automatic content
- // decompression.
- p.addLast(new HttpContentDecompressor());
-
- // Uncomment the following line if you don't want to handle
- // HttpContents.
- // p.addLast(new HttpObjectAggregator(1048576));
-
- p.addLast(new HttpSnoopClientHandler());
- }
- }
-
- public void connect(String strUrl)
- throws URISyntaxException, InterruptedException, SSLException {
- URI uri = new URI(strUrl);
-
- String scheme = uri.getScheme() == null ? "http" : uri.getScheme();
- String host = uri.getHost() == null ? "127.0.0.1" : uri.getHost();
-
- int port = uri.getPort();
-
- if (port == -1) {
- if ("http".equalsIgnoreCase(scheme)) {
- port = 80;
- } else if ("https".equalsIgnoreCase(scheme)) {
- port = 443;
- }
- }
-
- if (!"http".equalsIgnoreCase(scheme)
- && !"https".equalsIgnoreCase(scheme)) {
- return;
- }
-
- final boolean ssl = "https".equalsIgnoreCase(scheme);
- final SslContext sslCtx;
-
- if (ssl) {
- sslCtx = SslContextBuilder.forClient()
- .trustManager(InsecureTrustManagerFactory.INSTANCE).build();
- } else {
- sslCtx = null;
- }
-
- EventLoopGroup group = new NioEventLoopGroup();
-
- try {
- Bootstrap b = new Bootstrap();
- b.group(group);
- b.channel(NioSocketChannel.class);
- b.handler(new HttpClientInitializer(sslCtx));
-
- Channel ch = b.connect(host, port).sync().channel();
-
- HttpRequest request = new DefaultFullHttpRequest(
- HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath());
- request.headers().set(HttpHeaders.Names.HOST, host);
- request.headers().set(HttpHeaders.Names.CONNECTION,
- HttpHeaders.Values.CLOSE);
- request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING,
- HttpHeaders.Values.GZIP);
-
- request.headers().set(HttpHeaders.Names.COOKIE,
- ClientCookieEncoder.encode(
- new DefaultCookie("my-cookie", "foo"),
- new DefaultCookie("another-cookie", "bar")));
-
- ch.writeAndFlush(request);
-
- ch.closeFuture().sync();
- } finally {
- group.shutdownGracefully();
- }
- }
-
-}
+// package org.iotivity.cloud.base;
+//
+// import java.net.URI;
+// import java.net.URISyntaxException;
+//
+// import javax.net.ssl.SSLException;
+//
+// import io.netty.bootstrap.Bootstrap;
+// import io.netty.channel.Channel;
+// import io.netty.channel.ChannelHandlerContext;
+// import io.netty.channel.ChannelInitializer;
+// import io.netty.channel.ChannelPipeline;
+// import io.netty.channel.EventLoopGroup;
+// import io.netty.channel.SimpleChannelInboundHandler;
+// import io.netty.channel.nio.NioEventLoopGroup;
+// import io.netty.channel.socket.SocketChannel;
+// import io.netty.channel.socket.nio.NioSocketChannel;
+// import io.netty.handler.codec.http.ClientCookieEncoder;
+// import io.netty.handler.codec.http.DefaultCookie;
+// import io.netty.handler.codec.http.DefaultFullHttpRequest;
+// import io.netty.handler.codec.http.HttpClientCodec;
+// import io.netty.handler.codec.http.HttpContent;
+// import io.netty.handler.codec.http.HttpContentDecompressor;
+// import io.netty.handler.codec.http.HttpHeaders;
+// import io.netty.handler.codec.http.HttpMethod;
+// import io.netty.handler.codec.http.HttpObject;
+// import io.netty.handler.codec.http.HttpRequest;
+// import io.netty.handler.codec.http.HttpResponse;
+// import io.netty.handler.codec.http.HttpVersion;
+// import io.netty.handler.codec.http.LastHttpContent;
+// import io.netty.handler.ssl.SslContext;
+// import io.netty.handler.ssl.SslContextBuilder;
+// import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+// import io.netty.util.CharsetUtil;
+//
+// public class HttpClient {
+//
+// private static class HttpClientInitializer
+// extends ChannelInitializer<SocketChannel> {
+//
+// public static class HttpSnoopClientHandler
+// extends SimpleChannelInboundHandler<HttpObject> {
+//
+// @Override
+// public void channelRead0(ChannelHandlerContext ctx,
+// HttpObject msg) {
+// if (msg instanceof HttpResponse) {
+// HttpResponse response = (HttpResponse) msg;
+//
+// System.err.println("STATUS: " + response.getStatus());
+// System.err.println(
+// "VERSION: " + response.getProtocolVersion());
+// System.err.println();
+//
+// if (!response.headers().isEmpty()) {
+// for (String name : response.headers().names()) {
+// for (String value : response.headers()
+// .getAll(name)) {
+// System.err.println(
+// "HEADER: " + name + " = " + value);
+// }
+// }
+// System.err.println();
+// }
+//
+// if (HttpHeaders.isTransferEncodingChunked(response)) {
+// System.err.println("CHUNKED CONTENT {");
+// } else {
+// System.err.println("CONTENT {");
+// }
+// }
+// if (msg instanceof HttpContent) {
+// HttpContent content = (HttpContent) msg;
+//
+// System.err.print(
+// content.content().toString(CharsetUtil.UTF_8));
+// System.err.flush();
+//
+// if (content instanceof LastHttpContent) {
+// System.err.println("} END OF CONTENT");
+// ctx.close();
+// }
+// }
+// }
+//
+// @Override
+// public void exceptionCaught(ChannelHandlerContext ctx,
+// Throwable cause) {
+// cause.printStackTrace();
+// ctx.close();
+// }
+// }
+//
+// private final SslContext sslCtx;
+//
+// public HttpClientInitializer(SslContext sslCtx) {
+// this.sslCtx = sslCtx;
+// }
+//
+// @Override
+// public void initChannel(SocketChannel ch) {
+// ChannelPipeline p = ch.pipeline();
+//
+// // Enable HTTPS if necessary.
+// if (sslCtx != null) {
+// p.addLast(sslCtx.newHandler(ch.alloc()));
+// }
+//
+// p.addLast(new HttpClientCodec());
+//
+// // Remove the following line if you don't want automatic content
+// // decompression.
+// p.addLast(new HttpContentDecompressor());
+//
+// // Uncomment the following line if you don't want to handle
+// // HttpContents.
+// // p.addLast(new HttpObjectAggregator(1048576));
+//
+// p.addLast(new HttpSnoopClientHandler());
+// }
+// }
+//
+// public void connect(String strUrl)
+// throws URISyntaxException, InterruptedException, SSLException {
+// URI uri = new URI(strUrl);
+//
+// String scheme = uri.getScheme() == null ? "http" : uri.getScheme();
+// String host = uri.getHost() == null ? "127.0.0.1" : uri.getHost();
+//
+// int port = uri.getPort();
+//
+// if (port == -1) {
+// if ("http".equalsIgnoreCase(scheme)) {
+// port = 80;
+// } else if ("https".equalsIgnoreCase(scheme)) {
+// port = 443;
+// }
+// }
+//
+// if (!"http".equalsIgnoreCase(scheme)
+// && !"https".equalsIgnoreCase(scheme)) {
+// return;
+// }
+//
+// final boolean ssl = "https".equalsIgnoreCase(scheme);
+// final SslContext sslCtx;
+//
+// if (ssl) {
+// sslCtx = SslContextBuilder.forClient()
+// .trustManager(InsecureTrustManagerFactory.INSTANCE).build();
+// } else {
+// sslCtx = null;
+// }
+//
+// EventLoopGroup group = new NioEventLoopGroup();
+//
+// try {
+// Bootstrap b = new Bootstrap();
+// b.group(group);
+// b.channel(NioSocketChannel.class);
+// b.handler(new HttpClientInitializer(sslCtx));
+//
+// Channel ch = b.connect(host, port).sync().channel();
+//
+// HttpRequest request = new DefaultFullHttpRequest(
+// HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath());
+// request.headers().set(HttpHeaders.Names.HOST, host);
+// request.headers().set(HttpHeaders.Names.CONNECTION,
+// HttpHeaders.Values.CLOSE);
+// request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING,
+// HttpHeaders.Values.GZIP);
+//
+// request.headers().set(HttpHeaders.Names.COOKIE,
+// ClientCookieEncoder.encode(
+// new DefaultCookie("my-cookie", "foo"),
+// new DefaultCookie("another-cookie", "bar")));
+//
+// ch.writeAndFlush(request);
+//
+// ch.closeFuture().sync();
+// } finally {
+// group.shutdownGracefully();
+// }
+// }
+//
+// }
*
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
-package org.iotivity.cloud.base;
-
-import java.net.InetSocketAddress;
-import java.security.cert.CertificateException;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.net.ssl.SSLException;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandler;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import io.netty.handler.codec.http.HttpRequestDecoder;
-import io.netty.handler.codec.http.HttpResponseEncoder;
-import io.netty.handler.logging.LogLevel;
-import io.netty.handler.logging.LoggingHandler;
-import io.netty.util.concurrent.GenericFutureListener;
-
-public class HttpServer {
-
- private static class HttpServerInitializer
- extends ChannelInitializer<SocketChannel> {
-
- private List<ChannelHandler> additionalHandlers = new ArrayList<ChannelHandler>();
-
- public HttpServerInitializer() {
- }
-
- public void addHandler(ChannelHandler handler) {
- additionalHandlers.add(handler);
- }
-
- @Override
- public void initChannel(SocketChannel ch) {
- ChannelPipeline p = ch.pipeline();
- /*
- * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); }
- */
- p.addLast(new HttpRequestDecoder());
- // Uncomment the following line if you don't want to handle
- // HttpChunks.
- // p.addLast(new HttpObjectAggregator(1048576));
- p.addLast(new HttpResponseEncoder());
- // Remove the following line if you don't want automatic content
- // compression.
- // p.addLast(new HttpContentCompressor());
- for (ChannelHandler handler : additionalHandlers) {
- p.addLast(handler);
- }
- }
-
- }
-
- EventLoopGroup bossGroup = new NioEventLoopGroup(1);
-
- EventLoopGroup workerGroup = new NioEventLoopGroup();
-
- HttpServerInitializer initializer = new HttpServerInitializer();
-
- public void addHandler(ChannelHandler handler) {
- initializer.addHandler(handler);
- }
-
- public void startServer(InetSocketAddress inetSocketAddress)
- throws CertificateException, SSLException, InterruptedException {
-
- try {
- ServerBootstrap b = new ServerBootstrap();
- b.group(bossGroup, workerGroup);
- b.channel(NioServerSocketChannel.class);
- b.handler(new LoggingHandler(LogLevel.INFO));
-
- b.childHandler(initializer);
-
- ChannelFuture ch = b.bind(inetSocketAddress).sync();
- ch.addListener(new GenericFutureListener<ChannelFuture>() {
-
- @Override
- public void operationComplete(ChannelFuture future)
- throws Exception {
- // TODO Auto-generated method stub
- System.out
- .println("Connection status of TCP Http SERVER : "
- + future.isSuccess());
- }
-
- });
- } finally {
- }
-
- }
-
- public void stopServer() {
- // shut down all event loops
- if (bossGroup != null) {
- bossGroup.shutdownGracefully();
-
- try {
- bossGroup.terminationFuture().sync();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- if (workerGroup != null) {
- workerGroup.shutdownGracefully();
-
- try {
- workerGroup.terminationFuture().sync();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
-
-}
+// package org.iotivity.cloud.base;
+//
+// import java.net.InetSocketAddress;
+// import java.security.cert.CertificateException;
+// import java.util.ArrayList;
+// import java.util.List;
+//
+// import javax.net.ssl.SSLException;
+//
+// import io.netty.bootstrap.ServerBootstrap;
+// import io.netty.channel.ChannelFuture;
+// import io.netty.channel.ChannelHandler;
+// import io.netty.channel.ChannelInitializer;
+// import io.netty.channel.ChannelPipeline;
+// import io.netty.channel.EventLoopGroup;
+// import io.netty.channel.nio.NioEventLoopGroup;
+// import io.netty.channel.socket.SocketChannel;
+// import io.netty.channel.socket.nio.NioServerSocketChannel;
+// import io.netty.handler.codec.http.HttpRequestDecoder;
+// import io.netty.handler.codec.http.HttpResponseEncoder;
+// import io.netty.handler.logging.LogLevel;
+// import io.netty.handler.logging.LoggingHandler;
+// import io.netty.util.concurrent.GenericFutureListener;
+//
+// public class HttpServer {
+//
+// private static class HttpServerInitializer
+// extends ChannelInitializer<SocketChannel> {
+//
+// private List<ChannelHandler> additionalHandlers = new
+// ArrayList<ChannelHandler>();
+//
+// public HttpServerInitializer() {
+// }
+//
+// public void addHandler(ChannelHandler handler) {
+// additionalHandlers.add(handler);
+// }
+//
+// @Override
+// public void initChannel(SocketChannel ch) {
+// ChannelPipeline p = ch.pipeline();
+// /*
+// * if (sslCtx != null) { p.addLast(sslCtx.newHandler(ch.alloc())); }
+// */
+// p.addLast(new HttpRequestDecoder());
+// // Uncomment the following line if you don't want to handle
+// // HttpChunks.
+// // p.addLast(new HttpObjectAggregator(1048576));
+// p.addLast(new HttpResponseEncoder());
+// // Remove the following line if you don't want automatic content
+// // compression.
+// // p.addLast(new HttpContentCompressor());
+// for (ChannelHandler handler : additionalHandlers) {
+// p.addLast(handler);
+// }
+// }
+//
+// }
+//
+// EventLoopGroup bossGroup = new NioEventLoopGroup(1);
+//
+// EventLoopGroup workerGroup = new NioEventLoopGroup();
+//
+// HttpServerInitializer initializer = new HttpServerInitializer();
+//
+// public void addHandler(ChannelHandler handler) {
+// initializer.addHandler(handler);
+// }
+//
+// public void startServer(InetSocketAddress inetSocketAddress)
+// throws CertificateException, SSLException, InterruptedException {
+//
+// try {
+// ServerBootstrap b = new ServerBootstrap();
+// b.group(bossGroup, workerGroup);
+// b.channel(NioServerSocketChannel.class);
+// b.handler(new LoggingHandler(LogLevel.INFO));
+//
+// b.childHandler(initializer);
+//
+// ChannelFuture ch = b.bind(inetSocketAddress).sync();
+// ch.addListener(new GenericFutureListener<ChannelFuture>() {
+//
+// @Override
+// public void operationComplete(ChannelFuture future)
+// throws Exception {
+// // TODO Auto-generated method stub
+// System.out
+// .println("Connection status of TCP Http SERVER : "
+// + future.isSuccess());
+// }
+//
+// });
+// } finally {
+// }
+//
+// }
+//
+// public void stopServer() {
+// // shut down all event loops
+// if (bossGroup != null) {
+// bossGroup.shutdownGracefully();
+//
+// try {
+// bossGroup.terminationFuture().sync();
+// } catch (InterruptedException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+// }
+//
+// if (workerGroup != null) {
+// workerGroup.shutdownGracefully();
+//
+// try {
+// workerGroup.terminationFuture().sync();
+// } catch (InterruptedException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
+// }
+// }
+//
+// }
import java.util.ArrayList;
import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.util.Logger;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
@Sharable
public class ResourceManager extends SimpleChannelInboundHandler<CoapRequest> {
- private ArrayList<Resource> resources = new ArrayList<Resource>();
- SessionManager sessionManager = null;
-
- public ResourceManager() {
-
- }
-
- public ResourceManager(SessionManager sessionManager) {
- this.sessionManager = sessionManager;
- }
-
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) {
- ctx.flush();
- }
-
- @Override
- public void channelInactive(ChannelHandlerContext ctx) throws Exception {
- Logger.d("Channel Inactive");
- sessionManager.removeSessionByChannel(ctx);
- super.channelInactive(ctx);
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
-
- cause.printStackTrace();
- ctx.close();
- }
+ private ArrayList<Resource> resources = new ArrayList<Resource>();
@Override
public void channelRead0(ChannelHandlerContext ctx, CoapRequest request)
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
-
-import org.iotivity.cloud.util.Logger;
+import java.util.Map.Entry;
+import java.util.Objects;
import io.netty.channel.ChannelHandlerContext;
}
public void removeSessionByChannel(ChannelHandlerContext ctx) {
- synchronized (sessions) {
- if (!isThereCtxChannel(ctx)) {
- Logger.d("Already Session Removed : "
- + ctx.channel().toString());
- return;
- }
- Iterator<String> iterator = sessions.keySet().iterator();
- while (iterator.hasNext()) {
- String key = (String) iterator.next();
- if (ctx.channel().toString()
- .equals(querySession(key).channel().toString())) {
- Logger.d("Session Remove : " + ctx.channel().toString());
- removeSession(key);
- break;
- }
- }
+
+ String did = queryDid(ctx);
+ if (did != null) {
+ removeSession(did);
}
}
return ctx;
}
- public boolean isThereCtx(ChannelHandlerContext ctx) {
-
+ public String queryDid(ChannelHandlerContext ctx) {
synchronized (sessions) {
- return sessions.containsValue(ctx);
- }
- }
-
- public boolean isThereCtxChannel(ChannelHandlerContext ctx) {
-
- synchronized (sessions) {
- Iterator<String> iterator = sessions.keySet().iterator();
- while (iterator.hasNext()) {
- String key = (String) iterator.next();
- if (ctx.channel().toString()
- .equals(querySession(key).channel().toString())) {
- return true;
+ for (Entry<String, ChannelHandlerContext> entry : sessions
+ .entrySet()) {
+ if (Objects.equals(ctx, entry.getValue())) {
+ return entry.getKey();
}
}
- return false;
}
+
+ return null;
}
public List<String> getSessions() {
- return new ArrayList<String>(sessions.keySet());
+ synchronized (sessions) {
+ List<String> list = new ArrayList<String>(sessions.keySet());
+ return list;
+ }
}
}
for (int i = 0; i < 40; i++) {
List<byte[]> values = coapMessage.getOption(i);
if (values != null) {
- for (byte[] value : values) {
- writeOption(i - preOptionNum,
- value != null ? value.length : 0, byteBuf, value);
+ if (values.size() > 0) {
+ for (byte[] value : values) {
+ writeOption(i - preOptionNum,
+ value != null ? value.length : 0, byteBuf,
+ value);
+ preOptionNum = i;
+ }
+
+ } else {
+ writeOption(i - preOptionNum, 0, byteBuf, null);
preOptionNum = i;
}
}
public class CoapMessage {
- private int tokenLength = 0;
- protected int code = 0;
- private byte[] token = null;
+ private int tokenLength = 0;
+ protected int code = 0;
+ private byte[] token = null;
- private byte[] payload = null;
+ private byte[] payload = null;
// Option fields
protected List<byte[]> if_match = null;
protected byte[] proxy_uri = null;
protected byte[] proxy_scheme = null;
protected byte[] size1 = null;
- protected boolean observe = false;
+ protected byte[] observe = null;
public CoapMessage() {
}
// OBSERVE
case 6:
- observe = true;
+ observe = value;
break;
}
}
// ACCEPT
case 17:
- return accept != null ? Arrays.asList(content_format) : null;
+ return accept != null ? Arrays.asList(accept) : null;
// LOCATION_QUERY
case 20:
// OBSERVE
case 6:
- return observe == true ? new ArrayList<byte[]>() : null;
+ return observe != null ? Arrays.asList(observe) : null;
}
return null;
else {
decodedPayload = cbor.parsePayloadFromCbor(payload,
ArrayList.class);
+ String deviceId = null;
+ if (decodedPayload != null) {
+ HashMap<Object, Object> tags = (HashMap<Object, Object>) decodedPayload
+ .get(0);
- HashMap<Object, Object> tags = (HashMap<Object, Object>) decodedPayload
- .get(0);
+ deviceId = tags.get("di").toString();
- String deviceId = tags.get("di").toString();
+ if (deviceId == null) {
+ throw new IllegalArgumentException("deviceId is null");
+ }
- if (deviceId == null) {
- throw new IllegalArgumentException("deviceId is null");
+ Logger.i("deviceId : " + deviceId);
}
-
- Logger.i("deviceId : " + deviceId);
-
return deviceId;
}
}
}
public List<String> getUriPathSegments() {
+ if (uri_path == null) {
+ return null;
+ }
List<String> segments = new ArrayList<String>();
- if (uri_path != null) {
- for (byte[] pathSegment : uri_path) {
- segments.add(new String(pathSegment, StandardCharsets.UTF_8));
- }
+ for (byte[] pathSegment : uri_path) {
+ segments.add(new String(pathSegment, StandardCharsets.UTF_8));
}
return segments;
}
}
public List<String> getUriQuerySegments() {
+ if (uri_query == null) {
+ return null;
+ }
List<String> segments = new ArrayList<String>();
for (byte[] querySegment : uri_query) {
segments.add(new String(querySegment, StandardCharsets.UTF_8));
}
public void clearUriPath() {
- uri_path.clear();
- }
-
- public void setAccept(byte[] accepts) {
- accept = accepts;
+ if (uri_path != null) {
+ uri_path.clear();
+ }
}
}
*
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
-package org.iotivity.cloud.base.protocols.proxy;
-
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map.Entry;
-
-import org.iotivity.cloud.base.SessionManager;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
-import org.iotivity.cloud.base.protocols.coap.CoapResponse;
-import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
-import org.iotivity.cloud.util.Cbor;
-import org.iotivity.cloud.util.Logger;
-
-import io.netty.buffer.Unpooled;
-import io.netty.channel.ChannelDuplexHandler;
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandler.Sharable;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.http.DefaultFullHttpResponse;
-import io.netty.handler.codec.http.HttpHeaders;
-import io.netty.handler.codec.http.HttpMethod;
-import io.netty.handler.codec.http.HttpRequest;
-import io.netty.handler.codec.http.HttpResponse;
-import io.netty.handler.codec.http.HttpResponseStatus;
-import io.netty.handler.codec.http.HttpVersion;
-import io.netty.handler.codec.http.QueryStringDecoder;
-import io.netty.util.AttributeKey;
-import io.netty.util.CharsetUtil;
-
-@Sharable
-public class CoapHttpProxyHandler extends ChannelDuplexHandler {
-
- // Proxy converts http request to coaprequest and coapresponse to
- // httpresponse
- private SessionManager sessionManager = null;
-
- private static final AttributeKey<ChannelHandlerContext> keyHttpCtx = AttributeKey
- .newInstance("httpCtx");
-
- public CoapHttpProxyHandler(SessionManager sessionManager) {
- this.sessionManager = sessionManager;
- }
-
- @Override
- public void channelRead(ChannelHandlerContext ctx, Object msg)
- throws Exception {
-
- // in case of Receive Request from http
- if (msg instanceof HttpRequest) {
- // Check uri query param that contains coap device uuid
- // then search those and create coapRequest and send
- HttpRequest httpRequest = (HttpRequest) msg;
- QueryStringDecoder queryStringDecoder = new QueryStringDecoder(
- httpRequest.getUri());
-
- List<String> didList = queryStringDecoder.parameters().get("di");
-
- if (didList != null) {
- ChannelHandlerContext coapClient = sessionManager
- .querySession(didList.get(0));
-
- if (coapClient != null) {
- List<String> uriList = queryStringDecoder.parameters()
- .get("href");
- if (uriList != null) {
- coapClient.channel().attr(keyHttpCtx).set(ctx);
- coapClient.writeAndFlush(httpRequestToCoAPRequest(
- uriList.get(0), (HttpRequest) msg));
-
- return;
- }
- } else {
- Logger.d("Unable to find session: " + didList.get(0));
- }
- }
-
- // Prints available sessions to html
-
- ctx.writeAndFlush(printsAvailableSessions())
- .addListener(ChannelFutureListener.CLOSE);
- return;
- }
-
- if (msg instanceof CoapResponse) {
- ctx.channel().attr(keyHttpCtx).get()
- .writeAndFlush(
- coapResponseToHttpResponse((CoapResponse) msg))
- .addListener(ChannelFutureListener.CLOSE);
- return;
- }
-
- // Pass to upper-layer
- super.channelRead(ctx, msg);
- }
-
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
- cause.printStackTrace();
- ctx.close();
- }
-
- HttpResponse printsAvailableSessions() {
-
- StringBuilder strBuilder = new StringBuilder();
- List<String> sessions = sessionManager.getSessions();
-
- strBuilder.append("<html>");
- strBuilder.append("<b>Available sessions</b><br>");
-
- for (String session : sessions) {
- strBuilder.append(session);
- strBuilder.append("<br>");
- }
-
- strBuilder.append("</html>");
-
- HttpResponse response = new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
- Unpooled.copiedBuffer(strBuilder.toString(),
- CharsetUtil.UTF_8));
- response.headers().set(HttpHeaders.Names.CONTENT_TYPE,
- "text/html; charset=UTF-8");
-
- return response;
- }
-
- HttpResponse httpRequestToSendError() {
- HttpResponse response = new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND,
- Unpooled.copiedBuffer(
- "Failure: " + HttpResponseStatus.NOT_FOUND + "\r\n",
- CharsetUtil.UTF_8));
- response.headers().set(HttpHeaders.Names.CONTENT_TYPE,
- "text/html; charset=UTF-8");
-
- return response;
- }
-
- CoapRequest httpRequestToCoAPRequest(String uri, HttpRequest httpRequest) {
- CoapRequest coapRequest;
-
- // TODO: coapRequest converter required
- // coapRequest.getOptions().setUriQuery();
- if (httpRequest.getMethod() == HttpMethod.GET) {
- coapRequest = new CoapRequest(CoapMethod.GET);
- } else if (httpRequest.getMethod() == HttpMethod.PUT) {
- coapRequest = new CoapRequest(CoapMethod.PUT);
- } else if (httpRequest.getMethod() == HttpMethod.POST) {
- coapRequest = new CoapRequest(CoapMethod.POST);
- } else if (httpRequest.getMethod() == HttpMethod.DELETE) {
- coapRequest = new CoapRequest(CoapMethod.DELETE);
- } else {
- throw new IllegalArgumentException();
- }
-
- coapRequest.setUriPath(uri);
-
- return coapRequest;
- }
-
- HttpResponse coapResponseToHttpResponse(CoapResponse coapResponse) {
-
- Cbor<HashMap<String, Object>> cbor = new Cbor<HashMap<String, Object>>();
-
- HashMap<String, Object> rep = cbor
- .parsePayloadFromCbor(coapResponse.getPayload(), HashMap.class);
-
- StringBuilder strBuilder = new StringBuilder();
-
- for (Entry<String, Object> entry : rep.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue().toString();
- strBuilder.append("Key: " + key + " Value: " + value + "<br>");
- }
-
- HttpResponse httpResponse = new DefaultFullHttpResponse(
- HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
- Unpooled.wrappedBuffer(strBuilder.toString().getBytes(StandardCharsets.UTF_8)));
-
- httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE,
- "text/html; charset=UTF-8");
-
- // TODO: httpResponse converter required
-
- return httpResponse;
- }
-}
+// package org.iotivity.cloud.base.protocols.proxy;
+//
+// import java.nio.charset.StandardCharsets;
+// import java.util.HashMap;
+// import java.util.List;
+// import java.util.Map.Entry;
+//
+// import org.iotivity.cloud.base.SessionManager;
+// import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+// import org.iotivity.cloud.base.protocols.coap.CoapResponse;
+// import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
+// import org.iotivity.cloud.util.Cbor;
+// import org.iotivity.cloud.util.Logger;
+//
+// import io.netty.buffer.Unpooled;
+// import io.netty.channel.ChannelDuplexHandler;
+// import io.netty.channel.ChannelFutureListener;
+// import io.netty.channel.ChannelHandler.Sharable;
+// import io.netty.channel.ChannelHandlerContext;
+// import io.netty.handler.codec.http.DefaultFullHttpResponse;
+// import io.netty.handler.codec.http.HttpHeaders;
+// import io.netty.handler.codec.http.HttpMethod;
+// import io.netty.handler.codec.http.HttpRequest;
+// import io.netty.handler.codec.http.HttpResponse;
+// import io.netty.handler.codec.http.HttpResponseStatus;
+// import io.netty.handler.codec.http.HttpVersion;
+// import io.netty.handler.codec.http.QueryStringDecoder;
+// import io.netty.util.AttributeKey;
+// import io.netty.util.CharsetUtil;
+//
+// @Sharable
+// public class CoapHttpProxyHandler extends ChannelDuplexHandler {
+//
+// // Proxy converts http request to coaprequest and coapresponse to
+// // httpresponse
+// private SessionManager sessionManager = null;
+//
+// private static final AttributeKey<ChannelHandlerContext> keyHttpCtx =
+// AttributeKey
+// .newInstance("httpCtx");
+//
+// public CoapHttpProxyHandler(SessionManager sessionManager) {
+// this.sessionManager = sessionManager;
+// }
+//
+// @Override
+// public void channelRead(ChannelHandlerContext ctx, Object msg)
+// throws Exception {
+//
+// // in case of Receive Request from http
+// if (msg instanceof HttpRequest) {
+// // Check uri query param that contains coap device uuid
+// // then search those and create coapRequest and send
+// HttpRequest httpRequest = (HttpRequest) msg;
+// QueryStringDecoder queryStringDecoder = new QueryStringDecoder(
+// httpRequest.getUri());
+//
+// List<String> didList = queryStringDecoder.parameters().get("di");
+//
+// if (didList != null) {
+// ChannelHandlerContext coapClient = sessionManager
+// .querySession(didList.get(0));
+//
+// if (coapClient != null) {
+// List<String> uriList = queryStringDecoder.parameters()
+// .get("href");
+// if (uriList != null) {
+// coapClient.channel().attr(keyHttpCtx).set(ctx);
+// coapClient.writeAndFlush(httpRequestToCoAPRequest(
+// uriList.get(0), (HttpRequest) msg));
+//
+// return;
+// }
+// } else {
+// Logger.d("Unable to find session: " + didList.get(0));
+// }
+// }
+//
+// // Prints available sessions to html
+//
+// ctx.writeAndFlush(printsAvailableSessions())
+// .addListener(ChannelFutureListener.CLOSE);
+// return;
+// }
+//
+// if (msg instanceof CoapResponse) {
+// ctx.channel().attr(keyHttpCtx).get()
+// .writeAndFlush(
+// coapResponseToHttpResponse((CoapResponse) msg))
+// .addListener(ChannelFutureListener.CLOSE);
+// return;
+// }
+//
+// // Pass to upper-layer
+// super.channelRead(ctx, msg);
+// }
+//
+// @Override
+// public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+// cause.printStackTrace();
+// ctx.close();
+// }
+//
+// HttpResponse printsAvailableSessions() {
+//
+// StringBuilder strBuilder = new StringBuilder();
+// List<String> sessions = sessionManager.getSessions();
+//
+// strBuilder.append("<html>");
+// strBuilder.append("<b>Available sessions</b><br>");
+//
+// for (String session : sessions) {
+// strBuilder.append(session);
+// strBuilder.append("<br>");
+// }
+//
+// strBuilder.append("</html>");
+//
+// HttpResponse response = new DefaultFullHttpResponse(
+// HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
+// Unpooled.copiedBuffer(strBuilder.toString(),
+// CharsetUtil.UTF_8));
+// response.headers().set(HttpHeaders.Names.CONTENT_TYPE,
+// "text/html; charset=UTF-8");
+//
+// return response;
+// }
+//
+// HttpResponse httpRequestToSendError() {
+// HttpResponse response = new DefaultFullHttpResponse(
+// HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND,
+// Unpooled.copiedBuffer(
+// "Failure: " + HttpResponseStatus.NOT_FOUND + "\r\n",
+// CharsetUtil.UTF_8));
+// response.headers().set(HttpHeaders.Names.CONTENT_TYPE,
+// "text/html; charset=UTF-8");
+//
+// return response;
+// }
+//
+// CoapRequest httpRequestToCoAPRequest(String uri, HttpRequest httpRequest) {
+// CoapRequest coapRequest;
+//
+// // TODO: coapRequest converter required
+// // coapRequest.getOptions().setUriQuery();
+// if (httpRequest.getMethod() == HttpMethod.GET) {
+// coapRequest = new CoapRequest(CoapMethod.GET);
+// } else if (httpRequest.getMethod() == HttpMethod.PUT) {
+// coapRequest = new CoapRequest(CoapMethod.PUT);
+// } else if (httpRequest.getMethod() == HttpMethod.POST) {
+// coapRequest = new CoapRequest(CoapMethod.POST);
+// } else if (httpRequest.getMethod() == HttpMethod.DELETE) {
+// coapRequest = new CoapRequest(CoapMethod.DELETE);
+// } else {
+// throw new IllegalArgumentException();
+// }
+//
+// coapRequest.setUriPath(uri);
+//
+// return coapRequest;
+// }
+//
+// HttpResponse coapResponseToHttpResponse(CoapResponse coapResponse) {
+//
+// Cbor<HashMap<String, Object>> cbor = new Cbor<HashMap<String, Object>>();
+//
+// HashMap<String, Object> rep = cbor
+// .parsePayloadFromCbor(coapResponse.getPayload(), HashMap.class);
+//
+// StringBuilder strBuilder = new StringBuilder();
+//
+// for (Entry<String, Object> entry : rep.entrySet()) {
+// String key = entry.getKey();
+// String value = entry.getValue().toString();
+// strBuilder.append("Key: " + key + " Value: " + value + "<br>");
+// }
+//
+// HttpResponse httpResponse = new DefaultFullHttpResponse(
+// HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
+// Unpooled.wrappedBuffer(strBuilder.toString()
+// .getBytes(StandardCharsets.UTF_8)));
+//
+// httpResponse.headers().set(HttpHeaders.Names.CONTENT_TYPE,
+// "text/html; charset=UTF-8");
+//
+// // TODO: httpResponse converter required
+//
+// return httpResponse;
+// }
+// }
*/
package org.iotivity.cloud.util;
+import java.nio.charset.StandardCharsets;
+
import org.iotivity.cloud.base.protocols.coap.CoapMessage;
import org.iotivity.cloud.base.protocols.coap.CoapRequest;
Logger.d(strBuilder.toString());
ByteBuf outByteBuf = ctx.alloc().buffer();
- outByteBuf.writeBytes(message.getBytes());
+ outByteBuf.writeBytes(message.getBytes(StandardCharsets.UTF_8));
}
ctx.write(msg);
package org.iotivity.cloud.util;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
return value;
}
+
+ public static ArrayList<String> parseJSON(byte[] payload, String key) {
+
+ if (payload == null)
+ return null;
+
+ ArrayList<String> value = null;
+
+ try {
+ @SuppressWarnings("unchecked")
+ Map<String, ArrayList<String>> jsonMap = mapper.readValue(payload,
+ Map.class);
+ value = jsonMap.get(key);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+
+ return value;
+ }
public static Map<String, String> parseJSON(String jsonString)
throws JsonParseException, JsonMappingException, IOException {
+++ /dev/null
-/*
- *******************************************************************
- *
- * Copyright 2016 Samsung Electronics All Rights Reserved.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-package org.iotivity.cloud.util;
-
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
-import java.util.Enumeration;
-
-public class Net {
-
- public static String getMyIpAddress() {
-
- try {
- for (Enumeration<NetworkInterface> en = NetworkInterface
- .getNetworkInterfaces(); en.hasMoreElements();) {
- NetworkInterface intf = en.nextElement();
- for (Enumeration<InetAddress> enumIpAddr = intf
- .getInetAddresses(); enumIpAddr.hasMoreElements();) {
- InetAddress inetAddress = enumIpAddr.nextElement();
- if (!inetAddress.isLoopbackAddress()
- && !inetAddress.isLinkLocalAddress()
- && inetAddress.isSiteLocalAddress()) {
- return inetAddress.toString();
- }
- }
- }
- } catch (SocketException ex) {
- Logger.e("SocketException", ex);
- }
-
- return "";
- }
-}
package org.iotivity.cloud.base;
import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
import org.iotivity.cloud.base.protocols.coap.CoapRequest;
import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
+import org.iotivity.cloud.util.CoapLogHandler;
import org.junit.Test;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-
public class CoapClientTest {
-
- private static class CoapHandler
- extends SimpleChannelInboundHandler<CoapRequest> {
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, CoapRequest msg)
- throws Exception {
- // TODO Auto-generated method stub
- }
- }
-
@Test
public void testAddHandler() throws Exception {
CoapServer coapServer = new CoapServer();
coapServer.startServer(new InetSocketAddress(5683));
CoapClient coapClient = new CoapClient();
coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
- coapClient.addHandler(new CoapHandler());
+ coapClient.addHandler(new CoapLogHandler());
coapClient.stopClient();
coapServer.stopServer();
}
CoapClient coapClient = new CoapClient();
coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
- coapClient.addHandler(new CoapHandler());
+ coapClient.addHandler(new CoapLogHandler());
CoapRequest request = new CoapRequest(CoapMethod.GET);
coapClient.sendRequest(request);
CoapRequest request2 = new CoapRequest(CoapMethod.GET);
- request2.setToken("1234".getBytes());
+ request2.setToken("1234".getBytes(StandardCharsets.UTF_8));
coapClient.sendRequest(request2);
CoapRequest request3 = new CoapRequest(CoapMethod.GET);
- request3.setPayload("sample1".getBytes());
+ request3.setPayload("sample1".getBytes(StandardCharsets.UTF_8));
coapClient.sendRequest(request3);
CoapRequest request4 = new CoapRequest(CoapMethod.GET);
- request4.setToken("5576".getBytes());
- request4.setPayload("sample2".getBytes());
+ request4.setToken("5576".getBytes(StandardCharsets.UTF_8));
+ request4.setPayload("sample2".getBytes(StandardCharsets.UTF_8));
coapClient.sendRequest(request4);
CoapRequest request5 = new CoapRequest(CoapMethod.GET);
- request5.setToken("565761".getBytes());
+ request5.setToken("565761".getBytes(StandardCharsets.UTF_8));
coapClient.sendRequest(request5);
CoapRequest request6 = new CoapRequest(CoapMethod.GET);
import java.net.InetSocketAddress;
-import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.util.CoapLogHandler;
import org.junit.Test;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-
public class CoapServerTest {
- private static class CoapHandler
- extends SimpleChannelInboundHandler<CoapRequest> {
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, CoapRequest msg)
- throws Exception {
- // TODO Auto-generated method stub
- }
- }
-
@Test
public void testAddHandler() throws Exception {
CoapServer server = new CoapServer();
server.startServer(new InetSocketAddress(5683));
- server.addHandler(new CoapHandler());
+ server.addHandler(new CoapLogHandler());
server.stopServer();
}
--- /dev/null
+package org.iotivity.cloud.base;
+
+import java.net.InetSocketAddress;
+
+import org.iotivity.cloud.base.SessionManagerTest.CoapClientHandler;
+import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
+import org.junit.Test;
+
+import io.netty.channel.ChannelHandlerContext;
+
+public class ResourceManagerTest {
+
+ private static class SampleResource extends Resource {
+
+ public SampleResource() {
+ setUri("sampleUri");
+ }
+
+ @Override
+ public void onRequestReceived(ChannelHandlerContext ctx,
+ CoapRequest request) {
+ // TODO Auto-generated method stub
+ }
+ }
+
+ @Test
+ public void testChannelRead0ChannelHandlerContextCoapRequest()
+ throws Exception {
+
+ ResourceManager resourceManager = new ResourceManager();
+
+ resourceManager.registerResource(new SampleResource());
+
+ CoapServer coapServer = new CoapServer();
+ CoapClient coapClient = new CoapClient();
+ CoapClientHandler coapClientHandler = new CoapClientHandler();
+ coapServer.startServer(new InetSocketAddress(5683));
+ coapClient.addHandler(coapClientHandler);
+ coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
+
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriPath("sampleUri");
+
+ resourceManager.channelRead0(coapClientHandler.connectCtx, request);
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void testRegisterResource() {
+ ResourceManager resourceManager = new ResourceManager();
+
+ resourceManager.registerResource(new SampleResource());
+ }
+
+ @Test
+ public void testUnregisterResource() {
+ SampleResource sampleResource = new SampleResource();
+ ResourceManager resourceManager = new ResourceManager();
+
+ resourceManager.registerResource(sampleResource);
+ resourceManager.unregisterResource(sampleResource);
+ }
+}
\ No newline at end of file
--- /dev/null
+package org.iotivity.cloud.base;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.junit.Test;
+
+import io.netty.channel.ChannelHandlerContext;
+
+public class ResourceTest {
+
+ private static class SampleResource extends Resource {
+
+ public SampleResource() {
+ setUri("sampleUri");
+ }
+
+ @Override
+ public void onRequestReceived(ChannelHandlerContext ctx,
+ CoapRequest request) {
+ // TODO Auto-generated method stub
+ }
+ }
+
+ @Test
+ public void testGetSetUri() {
+ SampleResource sampleResource = new SampleResource();
+ assertEquals(sampleResource.getUri(), "sampleUri");
+ sampleResource.setUri("sampleUri2");
+ assertEquals(sampleResource.getUri(), "sampleUri2");
+ }
+
+ @Test
+ public void testGetSetType() {
+ SampleResource sampleResource = new SampleResource();
+ assertNull(sampleResource.getType());
+ sampleResource.setType("sampleType");
+ assertEquals(sampleResource.getType(), "sampleType");
+ }
+
+ @Test
+ public void testGetSetRif() {
+ SampleResource sampleResource = new SampleResource();
+ assertNull(sampleResource.getRif());
+ sampleResource.setRif("sampleRif");
+ assertEquals(sampleResource.getRif(), "sampleRif");
+ }
+
+ @Test
+ public void testOnRequestReceived() {
+
+ }
+}
--- /dev/null
+package org.iotivity.cloud.base;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.net.InetSocketAddress;
+
+import org.iotivity.cloud.base.protocols.coap.CoapResponse;
+import org.junit.Test;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+
+public class SessionManagerTest {
+
+ static class CoapClientHandler
+ extends SimpleChannelInboundHandler<CoapResponse> {
+
+ ChannelHandlerContext connectCtx = null;
+
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) throws Exception {
+ connectCtx = ctx;
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext arg0,
+ CoapResponse arg1) throws Exception {
+ // TODO Auto-generated method stub
+
+ }
+ }
+
+ @Test
+ public void testAddSession() throws Exception {
+ SessionManager sessionManager = new SessionManager();
+ CoapServer coapServer = new CoapServer();
+ CoapClient coapClient = new CoapClient();
+ CoapClientHandler coapClientHandler = new CoapClientHandler();
+ coapServer.startServer(new InetSocketAddress(5683));
+ coapClient.addHandler(coapClientHandler);
+ coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
+
+ sessionManager.addSession("sampleDid", coapClientHandler.connectCtx);
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void testRemoveSession() throws Exception {
+ SessionManager sessionManager = new SessionManager();
+ CoapServer coapServer = new CoapServer();
+ CoapClient coapClient = new CoapClient();
+ CoapClientHandler coapClientHandler = new CoapClientHandler();
+ coapServer.startServer(new InetSocketAddress(5683));
+ coapClient.addHandler(coapClientHandler);
+ coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
+
+ sessionManager.addSession("sampleDid", coapClientHandler.connectCtx);
+ sessionManager.removeSession("sampleDid");
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void testRemoveSessionByChannel() throws Exception {
+ SessionManager sessionManager = new SessionManager();
+ CoapServer coapServer = new CoapServer();
+ CoapClient coapClient = new CoapClient();
+ CoapClientHandler coapClientHandler = new CoapClientHandler();
+ coapServer.startServer(new InetSocketAddress(5683));
+ coapClient.addHandler(coapClientHandler);
+ coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
+
+ sessionManager.addSession("sampleDid", coapClientHandler.connectCtx);
+ sessionManager.removeSessionByChannel(coapClientHandler.connectCtx);
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+
+ @Test
+ public void testQuerySession() throws Exception {
+ SessionManager sessionManager = new SessionManager();
+ CoapServer coapServer = new CoapServer();
+ CoapClient coapClient = new CoapClient();
+ CoapClientHandler coapClientHandler = new CoapClientHandler();
+ coapServer.startServer(new InetSocketAddress(5683));
+ coapClient.addHandler(coapClientHandler);
+ coapClient.startClient(new InetSocketAddress("127.0.0.1", 5683));
+
+ sessionManager.addSession("sampleDid", coapClientHandler.connectCtx);
+ assertNotNull(sessionManager.querySession("sampleDid"));
+
+ coapClient.stopClient();
+ coapServer.stopServer();
+ }
+}
--- /dev/null
+package org.iotivity.cloud.base.protocols.coap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+
+import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
+import org.junit.Test;
+
+public class CoapRequestTest {
+
+ @Test
+ public void testCoapRequest() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ assertNotNull(request);
+ }
+
+ @Test
+ public void testGetRequestMethod() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ assertEquals(request.getRequestMethod(), CoapMethod.GET);
+ }
+
+ @Test
+ public void testSetUriPath() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriPath("sample");
+ }
+
+ @Test
+ public void testGetUriPath() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ assertNull(request.getUriPath());
+ request.setUriPath("sample");
+ assertEquals(request.getUriPath(), "sample");
+ }
+
+ @Test
+ public void testGetUriPathSegments() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ assertNull(request.getUriPathSegments());
+ request.setUriPath("parent/child");
+ List<String> list = request.getUriPathSegments();
+ if (list != null) {
+ assertEquals(list.size(), 2);
+ }
+ }
+
+ @Test
+ public void testSetUriQuery() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ request.setUriQuery("sample=sample");
+ }
+
+ @Test
+ public void testGetUriQuery() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ assertNull(request.getUriQuery());
+ request.setUriQuery("sample=sample");
+ assertEquals(request.getUriQuery(), "sample=sample");
+ }
+
+ @Test
+ public void testGetUriQuerySegments() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ assertNull(request.getUriQuerySegments());
+ request.setUriQuery("sample=samplle&sample2=sample2");
+ List<String> list = request.getUriQuerySegments();
+ if (list != null) {
+ assertEquals(list.size(), 2);
+ }
+ }
+
+ @Test
+ public void testClearUriPath() {
+ CoapRequest request = new CoapRequest(CoapMethod.GET);
+ assertNull(request.getUriPathSegments());
+ request.setUriPath("sample");
+ List<String> list = request.getUriPathSegments();
+ if (list != null) {
+ assertEquals(list.size(), 1);
+ }
+ request.clearUriPath();
+ list = request.getUriPathSegments();
+ if (list != null) {
+ assertEquals(list.size(), 0);
+ }
+ }
+}
--- /dev/null
+package org.iotivity.cloud.base.protocols.coap;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
+import org.junit.Test;
+
+public class CoapResponseTest {
+ @Test
+ public void testCoapResponse() throws Exception {
+ CoapResponse response = new CoapResponse(CoapStatus.VALID);
+ assertNotNull(response);
+ }
+
+ @Test
+ public void testGetResponseCode() throws Exception {
+ CoapResponse response = new CoapResponse(CoapStatus.VALID);
+ assertEquals(response.getResponseCode(), CoapStatus.VALID);
+ }
+}
--- /dev/null
+package org.iotivity.cloud.util;
+
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+
+import org.iotivity.cloud.base.CoapClient;
+import org.iotivity.cloud.base.CoapServer;
+import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.base.protocols.coap.enums.CoapMethod;
+import org.junit.Test;
+
+public class UtilTest {
+
+ @Test
+ public void testCbor() {
+ HashMap<String, String> setpayloadData = new HashMap<String, String>();
+ setpayloadData.put("test", "test");
+ }
+
+ @Test
+ public void testCoapLogHandler() throws Exception {
+ CoapServer server = new CoapServer();
+ server.startServer(new InetSocketAddress(5683));
+ server.addHandler(new CoapLogHandler());
+
+ CoapClient client = new CoapClient();
+ client.addHandler(new CoapLogHandler());
+ client.startClient(new InetSocketAddress("127.0.0.1", 5683));
+
+ CoapRequest request = new CoapRequest(CoapMethod.PUT);
+ client.sendRequest(request);
+
+ client.stopClient();
+ server.stopServer();
+ }
+
+ @Test
+ public void testJSONUtil() throws Exception {
+ HashMap<Object, Object> setpayloadData = new HashMap<Object, Object>();
+ setpayloadData.put("test", "test");
+
+ String msg = JSONUtil.writeJSON(setpayloadData);
+ JSONUtil.parseJSON(msg, "test");
+ JSONUtil.parseJSON(msg);
+ }
+
+ @Test
+ public void testLogger() throws Exception {
+ Logger.v("VERBOSE test");
+ Logger.d("DEBUG test");
+ Logger.i("INFO test");
+ Logger.e("ERROR test");
+ Logger.w("WARNING test");
+ }
+}
uint8 *record_header, uint8 *data, size_t data_length)
{
int err;
- dtls_handshake_parameters_t *handshake = peer->handshake_params;
/* A CCS message is handled after a KeyExchange message was
* received from the client. When security parameters have been
if (data_length < 1 || data[0] != 1)
return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR);
+ dtls_handshake_parameters_t *handshake = peer->handshake_params;
/* Just change the cipher when we are on the same epoch */
if (peer->role == DTLS_SERVER) {
err = calculate_key_block(ctx, handshake, peer,
dtls_info("decrypt_verify() failed\n");
if (peer->state < DTLS_STATE_CONNECTED) {
dtls_alert_send_from_err(ctx, peer, &peer->session, err);
+
+ (void)CALL(ctx, event, &peer->session,
+ DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_HANDSHAKE_FAILURE);
+
peer->state = DTLS_STATE_CLOSED;
/* dtls_stop_retransmission(ctx, peer); */
dtls_destroy_peer(ctx, peer, 1);
if (err < 0) {
dtls_warn("error while handling ChangeCipherSpec message\n");
dtls_alert_send_from_err(ctx, peer, session, err);
+ if (peer) {
+ (void)CALL(ctx, event, &peer->session,
+ DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_HANDSHAKE_FAILURE);
- /* invalidate peer */
- dtls_destroy_peer(ctx, peer, 1);
- peer = NULL;
-
+ /* invalidate peer */
+ dtls_destroy_peer(ctx, peer, 1);
+ peer = NULL;
+ }
return err;
}
break;
if (err < 0) {
dtls_warn("error while handling handshake packet\n");
dtls_alert_send_from_err(ctx, peer, session, err);
+
+ if (peer) {
+ (void)CALL(ctx, event, &peer->session,
+ DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_HANDSHAKE_FAILURE);
+ dtls_destroy_peer(ctx, peer, 1);
+ }
+
return err;
}
if (peer && peer->state == DTLS_STATE_CONNECTED) {
* see http://www.aarongifford.com/ */
#include "sha2/sha2.h"
-typedef SHA256_CTX dtls_hash_ctx;
+typedef DTLS_SHA256_CTX dtls_hash_ctx;
typedef dtls_hash_ctx *dtls_hash_t;
-#define DTLS_HASH_CTX_SIZE sizeof(SHA256_CTX)
+#define DTLS_HASH_CTX_SIZE sizeof(DTLS_SHA256_CTX)
static inline void
dtls_hash_init(dtls_hash_t ctx) {
- SHA256_Init((SHA256_CTX *)ctx);
+ DTLS_SHA256_Init((DTLS_SHA256_CTX *)ctx);
}
static inline void
dtls_hash_update(dtls_hash_t ctx, const unsigned char *input, size_t len) {
- SHA256_Update((SHA256_CTX *)ctx, input, len);
+ DTLS_SHA256_Update((DTLS_SHA256_CTX *)ctx, input, len);
}
static inline size_t
dtls_hash_finalize(unsigned char *buf, dtls_hash_t ctx) {
- SHA256_Final(buf, (SHA256_CTX *)ctx);
- return SHA256_DIGEST_LENGTH;
+ DTLS_SHA256_Final(buf, (DTLS_SHA256_CTX *)ctx);
+ return DTLS_SHA256_DIGEST_LENGTH;
}
#endif /* WITH_SHA256 */
/*** SHA-256/384/512 Various Length Definitions ***********************/
/* NOTE: Most of these are in sha2.h */
-#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
-#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
-#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
+#define DTLS_SHA256_SHORT_BLOCK_LENGTH (DTLS_SHA256_BLOCK_LENGTH - 8)
+#define DTLS_SHA384_SHORT_BLOCK_LENGTH (DTLS_SHA384_BLOCK_LENGTH - 16)
+#define DTLS_SHA512_SHORT_BLOCK_LENGTH (DTLS_SHA512_BLOCK_LENGTH - 16)
/*** ENDIAN REVERSAL MACROS *******************************************/
* library -- they are intended for private internal visibility/use
* only.
*/
-void SHA512_Last(SHA512_CTX*);
-void SHA256_Transform(SHA256_CTX*, const sha2_word32*);
-void SHA512_Transform(SHA512_CTX*, const sha2_word64*);
+void DTLS_SHA512_Last(DTLS_SHA512_CTX*);
+void DTLS_SHA256_Transform(DTLS_SHA256_CTX*, const sha2_word32*);
+void DTLS_SHA512_Transform(DTLS_SHA512_CTX*, const sha2_word64*);
#ifdef WITH_SHA256
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
/*** SHA-256: *********************************************************/
#ifdef WITH_SHA256
-void SHA256_Init(SHA256_CTX* context) {
- if (context == (SHA256_CTX*)0) {
+void DTLS_SHA256_Init(DTLS_SHA256_CTX* context) {
+ if (context == (DTLS_SHA256_CTX*)0) {
return;
}
- MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
- MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
+ MEMCPY_BCOPY(context->state, sha256_initial_hash_value, DTLS_SHA256_DIGEST_LENGTH);
+ MEMSET_BZERO(context->buffer, DTLS_SHA256_BLOCK_LENGTH);
context->bitcount = 0;
}
(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
j++
-void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+void DTLS_SHA256_Transform(DTLS_SHA256_CTX* context, const sha2_word32* data) {
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
sha2_word32 T1, *W256;
int j;
#else /* SHA2_UNROLL_TRANSFORM */
-void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) {
+void DTLS_SHA256_Transform(DTLS_SHA256_CTX* context, const sha2_word32* data) {
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
sha2_word32 T1, T2, *W256;
int j;
#endif /* SHA2_UNROLL_TRANSFORM */
-void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) {
+void DTLS_SHA256_Update(DTLS_SHA256_CTX* context, const sha2_byte *data, size_t len) {
unsigned int freespace, usedspace;
if (len == 0) {
}
/* Sanity check: */
- assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0);
+ assert(context != (DTLS_SHA256_CTX*)0 && data != (sha2_byte*)0);
- usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+ usedspace = (context->bitcount >> 3) % DTLS_SHA256_BLOCK_LENGTH;
if (usedspace > 0) {
/* Calculate how much free space is available in the buffer */
- freespace = SHA256_BLOCK_LENGTH - usedspace;
+ freespace = DTLS_SHA256_BLOCK_LENGTH - usedspace;
if (len >= freespace) {
/* Fill the buffer completely and process it */
context->bitcount += freespace << 3;
len -= freespace;
data += freespace;
- SHA256_Transform(context, (sha2_word32*)context->buffer);
+ DTLS_SHA256_Transform(context, (sha2_word32*)context->buffer);
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
return;
}
}
- while (len >= SHA256_BLOCK_LENGTH) {
+ while (len >= DTLS_SHA256_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA256_Transform(context, (sha2_word32*)data);
- context->bitcount += SHA256_BLOCK_LENGTH << 3;
- len -= SHA256_BLOCK_LENGTH;
- data += SHA256_BLOCK_LENGTH;
+ DTLS_SHA256_Transform(context, (sha2_word32*)data);
+ context->bitcount += DTLS_SHA256_BLOCK_LENGTH << 3;
+ len -= DTLS_SHA256_BLOCK_LENGTH;
+ data += DTLS_SHA256_BLOCK_LENGTH;
}
if (len > 0) {
/* There's left-overs, so save 'em */
usedspace = freespace = 0;
}
-void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) {
+void DTLS_SHA256_Final(sha2_byte digest[], DTLS_SHA256_CTX* context) {
sha2_word32 *d = (sha2_word32*)digest;
unsigned int usedspace;
/* Sanity check: */
- assert(context != (SHA256_CTX*)0);
+ assert(context != (DTLS_SHA256_CTX*)0);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte*)0) {
- usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
+ usedspace = (context->bitcount >> 3) % DTLS_SHA256_BLOCK_LENGTH;
#if BYTE_ORDER == LITTLE_ENDIAN
/* Convert FROM host byte order */
REVERSE64(context->bitcount,context->bitcount);
/* Begin padding with a 1 bit: */
context->buffer[usedspace++] = 0x80;
- if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
+ if (usedspace <= DTLS_SHA256_SHORT_BLOCK_LENGTH) {
/* Set-up for the last transform: */
- MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
+ MEMSET_BZERO(&context->buffer[usedspace], DTLS_SHA256_SHORT_BLOCK_LENGTH - usedspace);
} else {
- if (usedspace < SHA256_BLOCK_LENGTH) {
- MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
+ if (usedspace < DTLS_SHA256_BLOCK_LENGTH) {
+ MEMSET_BZERO(&context->buffer[usedspace], DTLS_SHA256_BLOCK_LENGTH - usedspace);
}
/* Do second-to-last transform: */
- SHA256_Transform(context, (sha2_word32*)context->buffer);
+ DTLS_SHA256_Transform(context, (sha2_word32*)context->buffer);
/* And set-up for the last transform: */
- MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+ MEMSET_BZERO(context->buffer, DTLS_SHA256_SHORT_BLOCK_LENGTH);
}
} else {
/* Set-up for the last transform: */
- MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
+ MEMSET_BZERO(context->buffer, DTLS_SHA256_SHORT_BLOCK_LENGTH);
/* Begin padding with a 1 bit: */
*context->buffer = 0x80;
}
/* Set the bit count: */
- *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
+ *(sha2_word64*)&context->buffer[DTLS_SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
/* Final transform: */
- SHA256_Transform(context, (sha2_word32*)context->buffer);
+ DTLS_SHA256_Transform(context, (sha2_word32*)context->buffer);
#if BYTE_ORDER == LITTLE_ENDIAN
{
}
}
#else
- MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
+ MEMCPY_BCOPY(d, context->state, DTLS_SHA256_DIGEST_LENGTH);
#endif
}
usedspace = 0;
}
-char *SHA256_End(SHA256_CTX* context, char buffer[]) {
- sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest;
+char *DTLS_SHA256_End(DTLS_SHA256_CTX* context, char buffer[]) {
+ sha2_byte digest[DTLS_SHA256_DIGEST_LENGTH], *d = digest;
int i;
/* Sanity check: */
- assert(context != (SHA256_CTX*)0);
+ assert(context != (DTLS_SHA256_CTX*)0);
if (buffer != (char*)0) {
- SHA256_Final(digest, context);
+ DTLS_SHA256_Final(digest, context);
- for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+ for (i = 0; i < DTLS_SHA256_DIGEST_LENGTH; i++) {
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
} else {
MEMSET_BZERO(context, sizeof(*context));
}
- MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
+ MEMSET_BZERO(digest, DTLS_SHA256_DIGEST_LENGTH);
return buffer;
}
-char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
- SHA256_CTX context;
+char* DTLS_SHA256_Data(const sha2_byte* data, size_t len, char digest[DTLS_SHA256_DIGEST_STRING_LENGTH]) {
+ DTLS_SHA256_CTX context;
- SHA256_Init(&context);
- SHA256_Update(&context, data, len);
- return SHA256_End(&context, digest);
+ DTLS_SHA256_Init(&context);
+ DTLS_SHA256_Update(&context, data, len);
+ return DTLS_SHA256_End(&context, digest);
}
#endif
/*** SHA-512: *********************************************************/
#ifdef WITH_SHA512
-void SHA512_Init(SHA512_CTX* context) {
- if (context == (SHA512_CTX*)0) {
+void DTLS_SHA512_Init(DTLS_SHA512_CTX* context) {
+ if (context == (DTLS_SHA512_CTX*)0) {
return;
}
- MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
- MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
+ MEMCPY_BCOPY(context->state, sha512_initial_hash_value, DTLS_SHA512_DIGEST_LENGTH);
+ MEMSET_BZERO(context->buffer, DTLS_SHA512_BLOCK_LENGTH);
context->bitcount[0] = context->bitcount[1] = 0;
}
(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
j++
-void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+void DTLS_SHA512_Transform(DTLS_SHA512_CTX* context, const sha2_word64* data) {
sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
sha2_word64 T1, *W512 = (sha2_word64*)context->buffer;
int j;
#else /* SHA2_UNROLL_TRANSFORM */
-void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) {
+void DTLS_SHA512_Transform(DTLS_SHA512_CTX* context, const sha2_word64* data) {
sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
int j;
#endif /* SHA2_UNROLL_TRANSFORM */
-void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) {
+void DTLS_SHA512_Update(DTLS_SHA512_CTX* context, const sha2_byte *data, size_t len) {
unsigned int freespace, usedspace;
if (len == 0) {
}
/* Sanity check: */
- assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
+ assert(context != (DTLS_SHA512_CTX*)0 && data != (sha2_byte*)0);
- usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+ usedspace = (context->bitcount[0] >> 3) % DTLS_SHA512_BLOCK_LENGTH;
if (usedspace > 0) {
/* Calculate how much free space is available in the buffer */
- freespace = SHA512_BLOCK_LENGTH - usedspace;
+ freespace = DTLS_SHA512_BLOCK_LENGTH - usedspace;
if (len >= freespace) {
/* Fill the buffer completely and process it */
ADDINC128(context->bitcount, freespace << 3);
len -= freespace;
data += freespace;
- SHA512_Transform(context, (sha2_word64*)context->buffer);
+ DTLS_SHA512_Transform(context, (sha2_word64*)context->buffer);
} else {
/* The buffer is not yet full */
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
return;
}
}
- while (len >= SHA512_BLOCK_LENGTH) {
+ while (len >= DTLS_SHA512_BLOCK_LENGTH) {
/* Process as many complete blocks as we can */
- SHA512_Transform(context, (sha2_word64*)data);
- ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
- len -= SHA512_BLOCK_LENGTH;
- data += SHA512_BLOCK_LENGTH;
+ DTLS_SHA512_Transform(context, (sha2_word64*)data);
+ ADDINC128(context->bitcount, DTLS_SHA512_BLOCK_LENGTH << 3);
+ len -= DTLS_SHA512_BLOCK_LENGTH;
+ data += DTLS_SHA512_BLOCK_LENGTH;
}
if (len > 0) {
/* There's left-overs, so save 'em */
usedspace = freespace = 0;
}
-void SHA512_Last(SHA512_CTX* context) {
+void DTLS_SHA512_Last(DTLS_SHA512_CTX* context) {
unsigned int usedspace;
- usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
+ usedspace = (context->bitcount[0] >> 3) % DTLS_SHA512_BLOCK_LENGTH;
#if BYTE_ORDER == LITTLE_ENDIAN
/* Convert FROM host byte order */
REVERSE64(context->bitcount[0],context->bitcount[0]);
/* Begin padding with a 1 bit: */
context->buffer[usedspace++] = 0x80;
- if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
+ if (usedspace <= DTLS_SHA512_SHORT_BLOCK_LENGTH) {
/* Set-up for the last transform: */
- MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
+ MEMSET_BZERO(&context->buffer[usedspace], DTLS_SHA512_SHORT_BLOCK_LENGTH - usedspace);
} else {
- if (usedspace < SHA512_BLOCK_LENGTH) {
- MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
+ if (usedspace < DTLS_SHA512_BLOCK_LENGTH) {
+ MEMSET_BZERO(&context->buffer[usedspace], DTLS_SHA512_BLOCK_LENGTH - usedspace);
}
/* Do second-to-last transform: */
- SHA512_Transform(context, (sha2_word64*)context->buffer);
+ DTLS_SHA512_Transform(context, (sha2_word64*)context->buffer);
/* And set-up for the last transform: */
- MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
+ MEMSET_BZERO(context->buffer, DTLS_SHA512_BLOCK_LENGTH - 2);
}
} else {
/* Prepare for final transform: */
- MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
+ MEMSET_BZERO(context->buffer, DTLS_SHA512_SHORT_BLOCK_LENGTH);
/* Begin padding with a 1 bit: */
*context->buffer = 0x80;
}
/* Store the length of input data (in bits): */
- *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
- *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
+ *(sha2_word64*)&context->buffer[DTLS_SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
+ *(sha2_word64*)&context->buffer[DTLS_SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
/* Final transform: */
- SHA512_Transform(context, (sha2_word64*)context->buffer);
+ DTLS_SHA512_Transform(context, (sha2_word64*)context->buffer);
}
-void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
+void DTLS_SHA512_Final(sha2_byte digest[], DTLS_SHA512_CTX* context) {
sha2_word64 *d = (sha2_word64*)digest;
/* Sanity check: */
- assert(context != (SHA512_CTX*)0);
+ assert(context != (DTLS_SHA512_CTX*)0);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte*)0) {
- SHA512_Last(context);
+ DTLS_SHA512_Last(context);
/* Save the hash data for output: */
#if BYTE_ORDER == LITTLE_ENDIAN
}
}
#else
- MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
+ MEMCPY_BCOPY(d, context->state, DTLS_SHA512_DIGEST_LENGTH);
#endif
}
MEMSET_BZERO(context, sizeof(context));
}
-char *SHA512_End(SHA512_CTX* context, char buffer[]) {
- sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest;
+char *DTLS_SHA512_End(DTLS_SHA512_CTX* context, char buffer[]) {
+ sha2_byte digest[DTLS_SHA512_DIGEST_LENGTH], *d = digest;
int i;
/* Sanity check: */
- assert(context != (SHA512_CTX*)0);
+ assert(context != (DTLS_SHA512_CTX*)0);
if (buffer != (char*)0) {
- SHA512_Final(digest, context);
+ DTLS_SHA512_Final(digest, context);
- for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
+ for (i = 0; i < DTLS_SHA512_DIGEST_LENGTH; i++) {
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
} else {
MEMSET_BZERO(context, sizeof(context));
}
- MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
+ MEMSET_BZERO(digest, DTLS_SHA512_DIGEST_LENGTH);
return buffer;
}
-char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
- SHA512_CTX context;
+char* DTLS_SHA512_Data(const sha2_byte* data, size_t len, char digest[DTLS_SHA512_DIGEST_STRING_LENGTH]) {
+ DTLS_SHA512_CTX context;
- SHA512_Init(&context);
- SHA512_Update(&context, data, len);
- return SHA512_End(&context, digest);
+ DTLS_SHA512_Init(&context);
+ DTLS_SHA512_Update(&context, data, len);
+ return DTLS_SHA512_End(&context, digest);
}
#endif
/*** SHA-384: *********************************************************/
#ifdef WITH_SHA384
-void SHA384_Init(SHA384_CTX* context) {
- if (context == (SHA384_CTX*)0) {
+void DTLS_SHA384_Init(DTLS_SHA384_CTX* context) {
+ if (context == (DTLS_SHA384_CTX*)0) {
return;
}
- MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
- MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
+ MEMCPY_BCOPY(context->state, sha384_initial_hash_value, DTLS_SHA512_DIGEST_LENGTH);
+ MEMSET_BZERO(context->buffer, DTLS_SHA384_BLOCK_LENGTH);
context->bitcount[0] = context->bitcount[1] = 0;
}
-void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) {
- SHA512_Update((SHA512_CTX*)context, data, len);
+void DTLS_SHA384_Update(DTLS_SHA384_CTX* context, const sha2_byte* data, size_t len) {
+ DTLS_SHA512_Update((DTLS_SHA512_CTX*)context, data, len);
}
-void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) {
+void DTLS_SHA384_Final(sha2_byte digest[], DTLS_SHA384_CTX* context) {
sha2_word64 *d = (sha2_word64*)digest;
/* Sanity check: */
- assert(context != (SHA384_CTX*)0);
+ assert(context != (DTLS_SHA384_CTX*)0);
/* If no digest buffer is passed, we don't bother doing this: */
if (digest != (sha2_byte*)0) {
- SHA512_Last((SHA512_CTX*)context);
+ DTLS_SHA512_Last((DTLS_SHA512_CTX*)context);
/* Save the hash data for output: */
#if BYTE_ORDER == LITTLE_ENDIAN
}
}
#else
- MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
+ MEMCPY_BCOPY(d, context->state, DTLS_SHA384_DIGEST_LENGTH);
#endif
}
MEMSET_BZERO(context, sizeof(context));
}
-char *SHA384_End(SHA384_CTX* context, char buffer[]) {
- sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest;
+char *DTLS_SHA384_End(DTLS_SHA384_CTX* context, char buffer[]) {
+ sha2_byte digest[DTLS_SHA384_DIGEST_LENGTH], *d = digest;
int i;
/* Sanity check: */
- assert(context != (SHA384_CTX*)0);
+ assert(context != (DTLS_SHA384_CTX*)0);
if (buffer != (char*)0) {
- SHA384_Final(digest, context);
+ DTLS_SHA384_Final(digest, context);
- for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
+ for (i = 0; i < DTLS_SHA384_DIGEST_LENGTH; i++) {
*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
*buffer++ = sha2_hex_digits[*d & 0x0f];
d++;
} else {
MEMSET_BZERO(context, sizeof(context));
}
- MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
+ MEMSET_BZERO(digest, DTLS_SHA384_DIGEST_LENGTH);
return buffer;
}
-char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
- SHA384_CTX context;
+char* DTLS_SHA384_Data(const sha2_byte* data, size_t len, char digest[DTLS_SHA384_DIGEST_STRING_LENGTH]) {
+ DTLS_SHA384_CTX context;
- SHA384_Init(&context);
- SHA384_Update(&context, data, len);
- return SHA384_End(&context, digest);
+ DTLS_SHA384_Init(&context);
+ DTLS_SHA384_Update(&context, data, len);
+ return DTLS_SHA384_End(&context, digest);
}
#endif
/*** SHA-256/384/512 Various Length Definitions ***********************/
-#define SHA256_BLOCK_LENGTH 64
-#define SHA256_DIGEST_LENGTH 32
-#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
-#define SHA384_BLOCK_LENGTH 128
-#define SHA384_DIGEST_LENGTH 48
-#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
-#define SHA512_BLOCK_LENGTH 128
-#define SHA512_DIGEST_LENGTH 64
-#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+#define DTLS_SHA256_BLOCK_LENGTH 64
+#define DTLS_SHA256_DIGEST_LENGTH 32
+#define DTLS_SHA256_DIGEST_STRING_LENGTH (DTLS_SHA256_DIGEST_LENGTH * 2 + 1)
+#define DTLS_SHA384_BLOCK_LENGTH 128
+#define DTLS_SHA384_DIGEST_LENGTH 48
+#define DTLS_SHA384_DIGEST_STRING_LENGTH (DTLS_SHA384_DIGEST_LENGTH * 2 + 1)
+#define DTLS_SHA512_BLOCK_LENGTH 128
+#define DTLS_SHA512_DIGEST_LENGTH 64
+#define DTLS_SHA512_DIGEST_STRING_LENGTH (DTLS_SHA512_DIGEST_LENGTH * 2 + 1)
/*** SHA-256/384/512 Context Structures *******************************/
*/
#ifdef SHA2_USE_INTTYPES_H
-typedef struct _SHA256_CTX {
+typedef struct _DTLS_SHA256_CTX {
uint32_t state[8];
uint64_t bitcount;
- uint8_t buffer[SHA256_BLOCK_LENGTH];
-} SHA256_CTX;
-typedef struct _SHA512_CTX {
+ uint8_t buffer[DTLS_SHA256_BLOCK_LENGTH];
+} DTLS_SHA256_CTX;
+typedef struct _DTLS_SHA512_CTX {
uint64_t state[8];
uint64_t bitcount[2];
- uint8_t buffer[SHA512_BLOCK_LENGTH];
-} SHA512_CTX;
+ uint8_t buffer[DTLS_SHA512_BLOCK_LENGTH];
+} DTLS_SHA512_CTX;
#else /* SHA2_USE_INTTYPES_H */
-typedef struct _SHA256_CTX {
+typedef struct _DTLS_SHA256_CTX {
u_int32_t state[8];
u_int64_t bitcount;
- u_int8_t buffer[SHA256_BLOCK_LENGTH];
-} SHA256_CTX;
-typedef struct _SHA512_CTX {
+ u_int8_t buffer[DTLS_SHA256_BLOCK_LENGTH];
+} DTLS_SHA256_CTX;
+typedef struct _DTLS_SHA512_CTX {
u_int64_t state[8];
u_int64_t bitcount[2];
- u_int8_t buffer[SHA512_BLOCK_LENGTH];
-} SHA512_CTX;
+ u_int8_t buffer[DTLS_SHA512_BLOCK_LENGTH];
+} DTLS_SHA512_CTX;
#endif /* SHA2_USE_INTTYPES_H */
-typedef SHA512_CTX SHA384_CTX;
+typedef DTLS_SHA512_CTX DTLS_SHA384_CTX;
/*** SHA-256/384/512 Function Prototypes ******************************/
#ifdef SHA2_USE_INTTYPES_H
#ifdef WITH_SHA256
-void SHA256_Init(SHA256_CTX *);
-void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t);
-void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
-char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
-char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+void DTLS_SHA256_Init(DTLS_SHA256_CTX *);
+void DTLS_SHA256_Update(DTLS_SHA256_CTX*, const uint8_t*, size_t);
+void DTLS_SHA256_Final(uint8_t[DTLS_SHA256_DIGEST_LENGTH], DTLS_SHA256_CTX*);
+char* DTLS_SHA256_End(DTLS_SHA256_CTX*, char[DTLS_SHA256_DIGEST_STRING_LENGTH]);
+char* DTLS_SHA256_Data(const uint8_t*, size_t, char[DTLS_SHA256_DIGEST_STRING_LENGTH]);
#endif
#ifdef WITH_SHA384
-void SHA384_Init(SHA384_CTX*);
-void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t);
-void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
-char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
-char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+void DTLS_SHA384_Init(DTLS_SHA384_CTX*);
+void DTLS_SHA384_Update(DTLS_SHA384_CTX*, const uint8_t*, size_t);
+void DTLS_SHA384_Final(uint8_t[DTLS_SHA384_DIGEST_LENGTH], SHA384_CTX*);
+char* DTLS_SHA384_End(DTLS_SHA384_CTX*, char[DTLS_SHA384_DIGEST_STRING_LENGTH]);
+char* DTLS_SHA384_Data(const uint8_t*, size_t, char[DTLS_SHA384_DIGEST_STRING_LENGTH]);
#endif
#ifdef WITH_SHA512
-void SHA512_Init(SHA512_CTX*);
-void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t);
-void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
-char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
-char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+void DTLS_SHA512_Init(DTLS_SHA512_CTX*);
+void DTLS_SHA512_Update(DTLS_SHA512_CTX*, const uint8_t*, size_t);
+void DTLS_SHA512_Final(uint8_t[DTLS_SHA512_DIGEST_LENGTH], DTLS_SHA512_CTX*);
+char* DTLS_SHA512_End(DTLS_SHA512_CTX*, char[DTLS_SHA512_DIGEST_STRING_LENGTH]);
+char* DTLS_SHA512_Data(const uint8_t*, size_t, char[DTLS_SHA512_DIGEST_STRING_LENGTH]);
#endif
#else /* SHA2_USE_INTTYPES_H */
#ifdef WITH_SHA256
-void SHA256_Init(SHA256_CTX *);
-void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t);
-void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*);
-char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
-char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]);
+void DTLS_SHA256_Init(DTLS_SHA256_CTX *);
+void DTLS_SHA256_Update(DTLS_SHA256_CTX*, const u_int8_t*, size_t);
+void DTLS_SHA256_Final(u_int8_t[DTLS_SHA256_DIGEST_LENGTH], DTLS_SHA256_CTX*);
+char* DTLS_SHA256_End(DTLS_SHA256_CTX*, char[DTLS_SHA256_DIGEST_STRING_LENGTH]);
+char* DTLS_SHA256_Data(const u_int8_t*, size_t, char[DTLS_SHA256_DIGEST_STRING_LENGTH]);
#endif
#ifdef WITH_SHA384
-void SHA384_Init(SHA384_CTX*);
-void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t);
-void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*);
-char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
-char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]);
+void DTLS_SHA384_Init(DTLS_SHA384_CTX*);
+void DTLS_SHA384_Update(DTLS_SHA384_CTX*, const u_int8_t*, size_t);
+void DTLS_SHA384_Final(u_int8_t[DTLS_SHA384_DIGEST_LENGTH], DTLS_SHA384_CTX*);
+char* DTLS_SHA384_End(DTLS_SHA384_CTX*, char[DTLS_SHA384_DIGEST_STRING_LENGTH]);
+char* DTLS_SHA384_Data(const u_int8_t*, size_t, char[DTLS_SHA384_DIGEST_STRING_LENGTH]);
#endif
#ifdef WITH_SHA512
-void SHA512_Init(SHA512_CTX*);
-void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t);
-void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
-char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
-char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]);
+void DTLS_SHA512_Init(DTLS_SHA512_CTX*);
+void DTLS_SHA512_Update(DTLS_SHA512_CTX*, const u_int8_t*, size_t);
+void DTLS_SHA512_Final(u_int8_t[DTLS_SHA512_DIGEST_LENGTH], DTLS_SHA512_CTX*);
+char* DTLS_SHA512_End(DTLS_SHA512_CTX*, char[DTLS_SHA512_DIGEST_STRING_LENGTH]);
+char* DTLS_SHA512_Data(const u_int8_t*, size_t, char[DTLS_SHA512_DIGEST_STRING_LENGTH]);
#endif
#endif /* SHA2_USE_INTTYPES_H */
#else /* NOPROTO */
#ifdef WITH_SHA256
-void SHA256_Init();
-void SHA256_Update();
-void SHA256_Final();
-char* SHA256_End();
-char* SHA256_Data();
+void DTLS_SHA256_Init();
+void DTLS_SHA256_Update();
+void DTLS_SHA256_Final();
+char* DTLS_SHA256_End();
+char* DTLS_SHA256_Data();
#endif
#ifdef WITH_SHA384
-void SHA384_Init();
-void SHA384_Update();
-void SHA384_Final();
-char* SHA384_End();
-char* SHA384_Data();
+void DTLS_SHA384_Init();
+void DTLS_SHA384_Update();
+void DTLS_SHA384_Final();
+char* DTLS_SHA384_End();
+char* DTLS_SHA384_Data();
#endif
#ifdef WITH_SHA512
-void SHA512_Init();
-void SHA512_Update();
-void SHA512_Final();
-char* SHA512_End();
-char* SHA512_Data();
+void DTLS_SHA512_Init();
+void DTLS_SHA512_Update();
+void DTLS_SHA512_Final();
+char* DTLS_SHA512_End();
+char* DTLS_SHA512_Data();
#endif
#endif /* NOPROTO */
int quiet = 0, hash = 0;
char *av, *file = (char*)0;
FILE *IN = (FILE*)0;
- SHA256_CTX ctx256;
- SHA384_CTX ctx384;
- SHA512_CTX ctx512;
+ DTLS_SHA256_CTX ctx256;
+ DTLS_SHA384_CTX ctx384;
+ DTLS_SHA512_CTX ctx512;
unsigned char buf[BUFLEN];
- SHA256_Init(&ctx256);
- SHA384_Init(&ctx384);
- SHA512_Init(&ctx512);
+ DTLS_SHA256_Init(&ctx256);
+ DTLS_SHA384_Init(&ctx384);
+ DTLSSHA512_Init(&ctx512);
/* Read data from STDIN by default */
fd = fileno(stdin);
kl = 0;
while ((l = read(fd,buf,BUFLEN)) > 0) {
kl += l;
- SHA256_Update(&ctx256, (unsigned char*)buf, l);
- SHA384_Update(&ctx384, (unsigned char*)buf, l);
- SHA512_Update(&ctx512, (unsigned char*)buf, l);
+ DTLS_SHA256_Update(&ctx256, (unsigned char*)buf, l);
+ DTLS_SHA384_Update(&ctx384, (unsigned char*)buf, l);
+ DTLS_SHA512_Update(&ctx512, (unsigned char*)buf, l);
}
if (file) {
fclose(IN);
}
if (hash & 1) {
- SHA256_End(&ctx256, buf);
+ DTLS_SHA256_End(&ctx256, buf);
if (!quiet)
printf("SHA-256 (%s) = ", file);
printf("%s\n", buf);
}
if (hash & 2) {
- SHA384_End(&ctx384, buf);
+ DTLS_SHA384_End(&ctx384, buf);
if (!quiet)
printf("SHA-384 (%s) = ", file);
printf("%s\n", buf);
}
if (hash & 4) {
- SHA512_End(&ctx512, buf);
+ DTLS_SHA512_End(&ctx512, buf);
if (!quiet)
printf("SHA-512 (%s) = ", file);
printf("%s\n", buf);
int main(int argc, char **argv) {
- SHA256_CTX c256;
- SHA384_CTX c384;
- SHA512_CTX c512;
+ DTLS_SHA256_CTX c256;
+ DTLS_SHA384_CTX c384;
+ DTLS_SHA512_CTX c512;
char buf[BUFSIZE];
- char md[SHA512_DIGEST_STRING_LENGTH];
+ char md[DTLS_SHA512_DIGEST_STRING_LENGTH];
int bytes, blocks, rep, i, j;
struct timeval start, end;
double t, ave256, ave384, ave512;
ave256 = ave384 = ave512 = 0;
best256 = best384 = best512 = 100000;
for (i = 0; i < rep; i++) {
- SHA256_Init(&c256);
- SHA384_Init(&c384);
- SHA512_Init(&c512);
+ DTLS_SHA256_Init(&c256);
+ DTLS_SHA384_Init(&c384);
+ DTLS_SHA512_Init(&c512);
gettimeofday(&start, (struct timezone*)0);
for (j = 0; j < blocks; j++) {
- SHA256_Update(&c256, (unsigned char*)buf, BUFSIZE);
+ DTLS_SHA256_Update(&c256, (unsigned char*)buf, BUFSIZE);
}
if (bytes % BUFSIZE) {
- SHA256_Update(&c256, (unsigned char*)buf, bytes % BUFSIZE);
+ DTLS_SHA256_Update(&c256, (unsigned char*)buf, bytes % BUFSIZE);
}
- SHA256_End(&c256, md);
+ DTLS_SHA256_End(&c256, md);
gettimeofday(&end, (struct timezone*)0);
t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0;
ave256 += t;
gettimeofday(&start, (struct timezone*)0);
for (j = 0; j < blocks; j++) {
- SHA384_Update(&c384, (unsigned char*)buf, BUFSIZE);
+ DTLS_SHA384_Update(&c384, (unsigned char*)buf, BUFSIZE);
}
if (bytes % BUFSIZE) {
- SHA384_Update(&c384, (unsigned char*)buf, bytes % BUFSIZE);
+ DTLS_SHA384_Update(&c384, (unsigned char*)buf, bytes % BUFSIZE);
}
- SHA384_End(&c384, md);
+ DTLS_SHA384_End(&c384, md);
gettimeofday(&end, (struct timezone*)0);
t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0;
ave384 += t;
gettimeofday(&start, (struct timezone*)0);
for (j = 0; j < blocks; j++) {
- SHA512_Update(&c512, (unsigned char*)buf, BUFSIZE);
+ DTLS_SHA512_Update(&c512, (unsigned char*)buf, BUFSIZE);
}
if (bytes % BUFSIZE) {
- SHA512_Update(&c512, (unsigned char*)buf, bytes % BUFSIZE);
+ DTLS_SHA512_Update(&c512, (unsigned char*)buf, bytes % BUFSIZE);
}
- SHA512_End(&c512, md);
+ DTLS_SHA512_End(&c512, md);
gettimeofday(&end, (struct timezone*)0);
t = ((end.tv_sec - start.tv_sec) * 1000000.0 + (end.tv_usec - start.tv_usec)) / 1000000.0;
ave512 += t;
#if DTLS_VERSION == 0xfeff
unsigned char statebuf[sizeof(md5_state_t) + sizeof(SHA_CTX)];
#elif DTLS_VERSION == 0xfefd
- unsigned char statebuf[sizeof(SHA256_CTX)];
+ unsigned char statebuf[sizeof(DTLS_SHA256_CTX)];
#endif
if (!hs_hash[0])
#endif
uint8 hash_buf[16 + SHA1_DIGEST_LENGTH];
#elif DTLS_VERSION == 0xfefd
- uint8 hash_buf[SHA256_DIGEST_LENGTH];
+ uint8 hash_buf[DTLS_SHA256_DIGEST_LENGTH];
#endif
#define verify_data_length 12
int is_client;
errno = 0;
size_t sizeValue = sizeof(value);
int strRet = snprintf(value, sizeValue, "%d", level);
+
if (strRet < 0 || strRet >= (int)sizeValue)
{
OIC_LOG_V(ERROR, TAG, "Failed to parse string due to errno: %d", errno);
* @return The number of bytes written to @p result or a value
* less than zero on error.
*/
-typedef int (*CAGetDTLSPskCredentialsHandler)( CADtlsPskCredType_t type,
- const unsigned char *desc, size_t desc_len,
- unsigned char *result, size_t result_length);
+typedef int (*CAGetDTLSPskCredentialsHandler)(CADtlsPskCredType_t type,
+ const uint8_t *desc, size_t desc_len,
+ uint8_t *result, size_t result_length);
/**
* Register callback to receive the result of DTLS handshake.
*/
#undef GET_SHA_256
#define GET_SHA_256(tbs, sha256) do{ \
- SHA256_CTX ctx256; \
- SHA256_Init(&ctx256); \
- SHA256_Update(&ctx256, tbs.data, tbs.len); \
- SHA256_Final(sha256, &ctx256); \
+ DTLS_SHA256_CTX ctx256; \
+ DTLS_SHA256_Init(&ctx256); \
+ DTLS_SHA256_Update(&ctx256, tbs.data, tbs.len); \
+ DTLS_SHA256_Final(sha256, &ctx256); \
}while(0)
/**@def CHECK_SIGN(structure, caPubKey)
#include "timer.h"
#include <netdb.h>
+/* tinyDTLS library error code */
+#define TINY_DTLS_ERROR (-1)
+/* tinyDTLS library success code */
+#define TINY_DTLS_SUCCESS (0)
+
#ifdef __WITH_X509__
#include "pki.h"
#include "crl.h"
if (NULL == g_caDtlsContext)
{
OIC_LOG(ERROR, NET_DTLS_TAG, "Context is NULL");
- return 0;
+ return TINY_DTLS_ERROR;
}
int type = 0;
}
OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
- return 0;
+ return TINY_DTLS_SUCCESS;
}
static int32_t CASendSecureData(dtls_context_t *context,
OIC_LOG(INFO, NET_DTLS_TAG, "Peer closing connection");
CARemovePeerFromPeerInfoList(peerAddr, port);
}
+ else if(DTLS_ALERT_LEVEL_FATAL == level && DTLS_ALERT_HANDSHAKE_FAILURE == code)
+ {
+ OIC_LOG(INFO, NET_DTLS_TAG, "Failed to DTLS handshake, the peer will be removed.");
+ CARemovePeerFromPeerInfoList(peerAddr, port);
+ }
OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT");
- return 0;
+ return TINY_DTLS_SUCCESS;
}
{
OIC_LOG(DEBUG, NET_DTLS_TAG, "IN");
- int32_t ret = -1;
+ int32_t ret = TINY_DTLS_ERROR;
if(NULL == ctx || NULL == session || NULL == result)
{
OIC_LOG(ERROR, NET_DTLS_TAG, "CAGetPskCredentials invalid parameters");
static int CAIsX509Active(struct dtls_context_t *ctx)
{
(void)ctx;
- return 0;
+ return TINY_DTLS_SUCCESS;
}
static int CAGetDeviceKey(struct dtls_context_t *ctx,
OIC_LOG(DEBUG, NET_DTLS_TAG, "CAGetDeviceKey");
static dtls_ecc_key_t ecdsa_key = {DTLS_ECDH_CURVE_SECP256R1, NULL, NULL, NULL};
- int ret = 1;
+ int ret = TINY_DTLS_ERROR;
VERIFY_SUCCESS(CAInitX509(), 0);
ecdsa_key.priv_key = g_X509Cred.devicePrivateKey;
*result = &ecdsa_key;
- ret = 0;
+ ret = TINY_DTLS_SUCCESS;
exit:
return ret;
}
size_t *cert_size)
{
OIC_LOG(DEBUG, NET_DTLS_TAG, "CAGetDeviceCertificate");
- int ret = 1;
+ int ret = TINY_DTLS_ERROR;
VERIFY_SUCCESS(CAInitX509(), 0);
PRINT_BYTE_ARRAY("OWN CERT: \n", ownCert);
#endif
- ret = 0;
+ ret = TINY_DTLS_SUCCESS;
exit:
return ret;
}
uint8_t chainLength;
- int ret;
+ int ret = TINY_DTLS_ERROR;
const unsigned char *ca_pub_x;
const unsigned char *ca_pub_y;
ByteArray certDerCode = BYTE_ARRAY_INITIALIZER;
if ( !ctx || !session || !cert || !x || !y)
{
- return -PKI_NULL_PASSED;
+ return TINY_DTLS_ERROR;
}
CAGetRootKey (&ca_pub_x, &ca_pub_y);
exit:
if (ret != 0)
{
- OIC_LOG(DEBUG, NET_DTLS_TAG, "Certificate verification FAILED\n");
+ OIC_LOG(ERROR, NET_DTLS_TAG, "Certificate verification FAILED\n");
+ return TINY_DTLS_ERROR;
}
else
{
OIC_LOG(DEBUG, NET_DTLS_TAG, "Certificate verification SUCCESS\n");
+ return TINY_DTLS_SUCCESS;
}
- return -ret;
}
#endif
jobject CAEDRNativeListen(JNIEnv *env);
/**
- * This function will listen the connection from remote device.
- * @param[in] env JNI interface pointer.
- * @param[in] socket server socket object.
- * @return JNI_TRUE or JNI_FALSE.
- */
-jboolean CAEDRIsConnectedForSocket(JNIEnv *env, jobject socket);
-
-/**
* This function will accept the connection from remote device.
* @param[in] env JNI interface pointer.
* @param[in] severSocketObject server socket object.
jobject gatt = CALEClientConnect(env, device,
CALEClientGetFlagFromState(env, jni_address,
CA_LE_AUTO_CONNECT_FLAG));
+
if (NULL == gatt)
{
OIC_LOG(ERROR, TAG, "CALEClientConnect has failed");
newstate->autoConnectFlag);
u_arraylist_add(g_deviceStateList, newstate); // update new state
}
-
ca_mutex_unlock(g_deviceStateListMutex);
return CA_STATUS_OK;
#ifndef SINGLE_THREAD
#include "caqueueingthread.h"
#endif
+#if defined(__TIZEN__) || defined(__ANDROID__)
+#include "caleserver.h"
+#include "caleclient.h"
+#endif
#include "oic_malloc.h"
#include "oic_string.h"
#include "caremotehandler.h"
if (!coap_add_data(*pdu, dataLength, (const unsigned char *) info->payload))
{
OIC_LOG(INFO, TAG, "it have to use block");
+ res = CA_STATUS_FAILED;
+ goto exit;
}
else
{
{
return res;
}
- return CA_STATUS_FAILED;
+ else
+ {
+ return CA_STATUS_FAILED;
+ }
}
// #3. add data into result
uint8_t rawIPAddr[4];
char address[16];
W5100.getIPAddress(rawIPAddr);
- sprintf(address, "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2], rawIPAddr[3]);
+ snprintf(address, sizeof(address), "%d.%d.%d.%d", rawIPAddr[0], rawIPAddr[1], rawIPAddr[2],
+ rawIPAddr[3]);
OIC_LOG_V(DEBUG, TAG, "address:%s", address);
int serverFD = 1;
if (CAArduinoInitUdpSocket(port, &serverFD) != CA_STATUS_OK)
// wifi shield does not support multicast
OIC_LOG(DEBUG, TAG, "IN");
OIC_LOG(DEBUG, TAG, "OUT");
- return CA_NOT_SUPPORTED;
+ //Arduino wifi shiled does not support multicast.
+ //OCInit() is failing if an error code is returned here,
+ //hence blocking even uni-cast operations.
+ //So default return value is changed to CA_STATUS_OK.
+ return CA_STATUS_OK;
}
CAResult_t CAIPStartServer()
applyMulticastToInterface4(inaddr);
}
}
-static void CAHandleNetlink()
-{
-}
void CAIPSetPacketReceiveCallback(CAIPPacketReceivedCallback callback)
{
FD_CLR(caglobals.tcp.connectionFds[0], readFds);
return;
}
+ else if (-1 != caglobals.tcp.connectionFds[0] &&
+ FD_ISSET(caglobals.tcp.connectionFds[0], readFds))
+ {
+ // new connection was created from remote device.
+ // exit the function to update read file descriptor.
+ char buf[MAX_ADDR_STR_SIZE_CA] = {0};
+ ssize_t len = read(caglobals.tcp.connectionFds[0], buf, sizeof (buf));
+ if (-1 == len)
+ {
+ return;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Received new connection event with [%s]", buf);
+ FD_CLR(caglobals.tcp.connectionFds[0], readFds);
+ return;
+ }
else
{
uint32_t length = u_arraylist_length(caglobals.tcp.svrlist);
--- /dev/null
+/* ****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <bluetooth.h>
+#include <bluetooth_type.h>
+#include <bluetooth_internal.h>
+
+#include "camanagerleinterface.h"
+#include "cacommon.h"
+#include "camessagehandler.h"
+#include "caleserver.h"
+#include "cagattservice.h"
+#include "logger.h"
+
+#define TAG "OIC_CA_MANAGER_TZ_LE"
+
+static CAAdapterStateChangedCB g_adapterStateCB = NULL;
+static CAConnectionStateChangedCB g_connStateCB = NULL;
+
+static void CAManagerAdapterMonitorHandler(const CAEndpoint_t *info, CANetworkStatus_t status);
+static void CAManagerConnectionMonitorHandler(CATransportAdapter_t adapter,
+ const char *remoteAddress, bool connected);
+
+void CASetLENetworkMonitorCallbacks(CAAdapterStateChangedCB adapterStateCB,
+ CAConnectionStateChangedCB connStateCB)
+{
+ OIC_LOG(DEBUG, TAG, "CASetLENetworkMonitorCallbacks");
+
+ g_adapterStateCB = adapterStateCB;
+ CASetNetworkMonitorCallback(CAManagerAdapterMonitorHandler);
+
+ g_connStateCB = connStateCB;
+ CASetLEConnectionStateChangedCallback(CAManagerConnectionMonitorHandler);
+}
+
+void CAStartServerLEAdvertising()
+{
+ OIC_LOG(DEBUG, TAG, "CAStartServerLEAdvertising");
+
+ CAResult_t res = CALEStartAdvertise(CA_GATT_SERVICE_UUID);
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to start le advertising [%d]", res);
+ return;
+ }
+}
+
+void CAStopServerLEAdvertising()
+{
+ OIC_LOG(DEBUG, TAG, "CAStopServerLEAdvertising");
+
+ CAResult_t res = CALEStopAdvertise();
+ if (CA_STATUS_OK != res)
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to stop le advertising [%d]", res);
+ return;
+ }
+}
+
+CAResult_t CASetLEClientAutoConnectionDeviceInfo(const char * address)
+{
+ OIC_LOG(DEBUG, TAG, "CASetLEClientAutoConnectionDeviceInfo");
+ (void)address;
+ return CA_NOT_SUPPORTED;
+}
+
+CAResult_t CAUnsetLEClientAutoConnectionDeviceInfo(const char * address)
+{
+ OIC_LOG(DEBUG, TAG, "CAUnsetLEClientAutoConnectionDeviceInfo");
+ (void)address;
+ return CA_NOT_SUPPORTED;
+}
+
+static void CAManagerAdapterMonitorHandler(const CAEndpoint_t *info, CANetworkStatus_t status)
+{
+ if (CA_INTERFACE_DOWN == status)
+ {
+ if (info && g_adapterStateCB)
+ {
+ g_adapterStateCB(info->adapter, false);
+ OIC_LOG(DEBUG, TAG, "Pass the disabled adapter state to upper layer");
+ }
+ }
+ else if (CA_INTERFACE_UP == status)
+ {
+ if (info && g_adapterStateCB)
+ {
+ g_adapterStateCB(info->adapter, true);
+ OIC_LOG(DEBUG, TAG, "Pass the enabled adapter state to upper layer");
+ }
+ }
+}
+
+static void CAManagerConnectionMonitorHandler(CATransportAdapter_t adapter,
+ const char *remoteAddress, bool connected)
+{
+ (void)adapter;
+
+ if (!remoteAddress)
+ {
+ OIC_LOG(ERROR, TAG, "remoteAddress is NULL");
+ return;
+ }
+
+ if (connected)
+ {
+ if (g_connStateCB)
+ {
+ g_connStateCB(CA_ADAPTER_GATT_BTLE, remoteAddress, true);
+ OIC_LOG(DEBUG, TAG, "Pass the connected device info to upper layer");
+
+ // stop le advertising
+ CAStopServerLEAdvertising();
+ }
+ }
+ else
+ {
+ if (g_connStateCB)
+ {
+ g_connStateCB(CA_ADAPTER_GATT_BTLE, remoteAddress, false);
+ OIC_LOG(DEBUG, TAG, "Pass the disconnected device info to upper layer");
+
+ // start le advertising to receive new connection request.
+ CAStartServerLEAdvertising();
+ }
+ }
+}
import os
env.AppendUnique(CPPPATH = [os.path.join(Dir('.').abspath, './include')])
-
+if env.get('TARGET_OS') in ['arduino']:
+ env.AppendUnique(CPPPATH = [os.path.join(env.get('BUILD_DIR'), 'resource/c_common/oic_string/include')])
if env.get('TARGET_OS') == 'tizen':
env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
else:
#elif defined ARDUINO
#include <stdarg.h>
#include "Arduino.h"
+#include "oic_string.h"
PROGMEM const char level0[] = "DEBUG";
PROGMEM const char level1[] = "INFO";
static void OCLogString(LogLevel level, PROGMEM const char * tag, PROGMEM const char * logStr);
#ifdef ARDUINO_ARCH_AVR
//Mega2560 and other 8-bit AVR microcontrollers
- #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_word(addr));}
+ #define GET_PROGMEM_BUFFER(buffer, addr) { OICStrcpy(buffer, sizeof(buffer), (char*)pgm_read_word(addr));}
#elif defined ARDUINO_ARCH_SAM
//Arduino Due and other 32-bit ARM micro-controllers
- #define GET_PROGMEM_BUFFER(buffer, addr) { strcpy_P(buffer, (char*)pgm_read_dword(addr));}
+ #define GET_PROGMEM_BUFFER(buffer, addr) { OICStrcpy(buffer, sizeof(buffer), (char*)pgm_read_dword(addr));}
#else
#define GET_PROGMEM_BUFFER(buffer, addr) { buffer[0] = '\0';}
#endif
{
NOR = 0, /**< Normal Message. */
ACK, /**< Empty Acknowledgement message. */
- RST, /**< Empty Reset message. */
- UNDEFINED /**< Message type not defined. */
+ RST /**< Empty Reset message. */
}MSGType;
/**
#define RM_TAG "OIC_RM_RAP"
/**
+ * Default routing option data length is 1 byte with any of the following values.
+ * 00 - source and destination address is not present.
+ * 01 - source and destination address is present with message type as ACK.
+ * 10 - source and destination address is present with message type as RESET.
+ * 11 - source and destination address is present with message type as NORMAL.
+ */
+#define DEFAULT_ROUTE_OPTION_LEN 1
+
+/**
* Minimum routing option data length is
- * length of src address(1byte) + length of destination address(1byte) +
- * Seq Num(2bytes) + Msg Type(1 bytes)
+ * Msg Type(1 bytes) + length of src address(1byte) + length of destination address(1byte) +
+ * Seq Num(2bytes)
*/
#define MIN_ROUTE_OPTION_LEN 5
/**
+ * Acknowledge message type is denoted as 01000000
+ */
+#define ACK_MESSAGE_TYPE (1 << 6)
+
+/**
+ * Reset message type is denoted as 10000000
+ */
+#define RST_MESSAGE_TYPE (1 << 7)
+
+/**
+ * Normal message type is denoted as 11000000
+ */
+#define NORMAL_MESSAGE_TYPE (3 << 6)
+
+/**
* Stack mode.
*/
static OCMode g_rmStackMode = OC_CLIENT;
}
// Update Endpoint with source address from RM header option.
- if (0 != (*options + routeIndex)->optionLength)
+ if (DEFAULT_ROUTE_OPTION_LEN < (*options + routeIndex)->optionLength )
{
uint8_t dLen = 0;
- uint16_t count = sizeof(dLen);
- memcpy(&dLen, (*options + routeIndex)->optionData, sizeof(dLen));
+ uint16_t count = sizeof(dLen) + DEFAULT_ROUTE_OPTION_LEN;
+ memcpy(&dLen, (*options + routeIndex)->optionData + DEFAULT_ROUTE_OPTION_LEN, sizeof(dLen));
count += dLen;
uint8_t sLen = 0;
memcpy(&sLen, (*options + routeIndex)->optionData + count, sizeof(sLen));
(optValue->srcEp ? ENDPOINT_ID_LENGTH:0);
OIC_LOG_V(DEBUG, RM_TAG, "createoption dlen %u slen [%u]", dLen, sLen);
- unsigned int totalLength = MIN_ROUTE_OPTION_LEN + dLen + sLen;
- void *tempData = OICCalloc(totalLength, sizeof(char));
- if (NULL == tempData)
+
+ unsigned int totalLength = 0;
+ void *tempData = NULL;
+ if (0 == dLen && 0 == sLen)
{
- OIC_LOG(ERROR, RM_TAG, "Calloc failed");
- return OC_STACK_NO_MEMORY;
+ OIC_LOG(DEBUG, RM_TAG, "Source and destination is not present");
+ totalLength = DEFAULT_ROUTE_OPTION_LEN;
+ tempData = OICCalloc(totalLength, sizeof(char));
+ if (NULL == tempData)
+ {
+ OIC_LOG(ERROR, RM_TAG, "Calloc failed");
+ return OC_STACK_NO_MEMORY;
+ }
+
+ if (ACK == optValue->msgType)
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue ACK Message Type");
+ memset(tempData, ACK_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
+ else if (RST == optValue->msgType)
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue RST Message Type");
+ memset(tempData, RST_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
+ else
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue NOR Message Type");
+ memset(tempData, NORMAL_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
}
- memcpy(tempData, &dLen, sizeof(dLen));
- unsigned int count = sizeof(dLen);
- if (0 < dLen)
+ else
{
- if (optValue->destGw)
+ totalLength = MIN_ROUTE_OPTION_LEN + dLen + sLen;
+ tempData = OICCalloc(totalLength, sizeof(char));
+ if (NULL == tempData)
{
- memcpy(tempData + count, &(optValue->destGw), GATEWAY_ID_LENGTH);
- count += GATEWAY_ID_LENGTH;
+ OIC_LOG(ERROR, RM_TAG, "Calloc failed");
+ return OC_STACK_NO_MEMORY;
}
- if (optValue->destEp)
+ if (ACK == optValue->msgType)
{
- memcpy(tempData + count, &(optValue->destEp), ENDPOINT_ID_LENGTH);
- count += ENDPOINT_ID_LENGTH;
+ OIC_LOG(DEBUG, RM_TAG, "OptValue ACK Message Type");
+ memset(tempData, ACK_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
+ else if (RST == optValue->msgType)
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue RST Message Type");
+ memset(tempData, RST_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
+ }
+ else
+ {
+ OIC_LOG(DEBUG, RM_TAG, "OptValue NOR Message Type");
+ memset(tempData, NORMAL_MESSAGE_TYPE, DEFAULT_ROUTE_OPTION_LEN);
}
- }
- memcpy(tempData + count, &sLen, sizeof(sLen));
- count += sizeof(sLen);
- if (0 < sLen)
- {
- if (optValue->srcGw)
+ memcpy(tempData + DEFAULT_ROUTE_OPTION_LEN, &dLen, sizeof(dLen));
+ unsigned int count = sizeof(dLen) + DEFAULT_ROUTE_OPTION_LEN;
+ if (0 < dLen)
{
- memcpy(tempData + count, &(optValue->srcGw), GATEWAY_ID_LENGTH);
- count += GATEWAY_ID_LENGTH;
+ if (optValue->destGw)
+ {
+ memcpy(tempData + count, &(optValue->destGw), GATEWAY_ID_LENGTH);
+ count += GATEWAY_ID_LENGTH;
+ }
+
+ if (optValue->destEp)
+ {
+ memcpy(tempData + count, &(optValue->destEp), ENDPOINT_ID_LENGTH);
+ count += ENDPOINT_ID_LENGTH;
+ }
}
- if (optValue->srcEp)
+ memcpy(tempData + count, &sLen, sizeof(sLen));
+ count += sizeof(sLen);
+ if (0 < sLen)
{
- memcpy(tempData + count, &(optValue->srcEp), ENDPOINT_ID_LENGTH);
- count += ENDPOINT_ID_LENGTH;
+ if (optValue->srcGw)
+ {
+ memcpy(tempData + count, &(optValue->srcGw), GATEWAY_ID_LENGTH);
+ count += GATEWAY_ID_LENGTH;
+ }
+
+ if (optValue->srcEp)
+ {
+ memcpy(tempData + count, &(optValue->srcEp), ENDPOINT_ID_LENGTH);
+ count += ENDPOINT_ID_LENGTH;
+ }
}
+
+ memcpy(tempData + count, &optValue->mSeqNum, sizeof(optValue->mSeqNum));
}
- memcpy(tempData + count, &optValue->mSeqNum, sizeof(optValue->mSeqNum));
- count += sizeof(optValue->mSeqNum);
- memcpy(tempData + count, &optValue->msgType, sizeof(optValue->msgType));
memcpy(options->optionData, tempData, totalLength);
options->optionID = RM_OPTION_MESSAGE_SWITCHING;
return OC_STACK_ERROR;
}
- uint8_t dLen = 0 ;
- uint16_t count = sizeof(dLen);
- memcpy(&dLen, options->optionData, sizeof(dLen));
- if (0 < dLen)
- {
- memcpy(&(optValue->destGw), options->optionData + count, GATEWAY_ID_LENGTH);
- count += GATEWAY_ID_LENGTH;
+ OIC_LOG_V(DEBUG, RM_TAG, "Option Length is %d", options->optionLength);
+ uint8_t mType = 0;
+ memcpy(&mType, options->optionData, sizeof(mType));
- if (GATEWAY_ID_LENGTH < dLen)
- {
- memcpy(&(optValue->destEp), options->optionData + count, ENDPOINT_ID_LENGTH);
- count += ENDPOINT_ID_LENGTH;
- }
+ if (ACK_MESSAGE_TYPE == mType)
+ {
+ OIC_LOG(INFO, RM_TAG, "ACK_MESSAGE_TYPE");
+ optValue->msgType = ACK;
+ }
+ else if (RST_MESSAGE_TYPE == mType)
+ {
+ OIC_LOG(INFO, RM_TAG, "RST_MESSAGE_TYPE");
+ optValue->msgType = RST;
+ }
+ else if (NORMAL_MESSAGE_TYPE == mType)
+ {
+ OIC_LOG(INFO, RM_TAG, "NOR_MESSAGE_TYPE");
+ optValue->msgType = NOR;
}
- uint8_t sLen = 0;
- memcpy(&sLen, options->optionData + count, sizeof(sLen));
- count += sizeof(sLen);
- if (0 < sLen)
+ if (DEFAULT_ROUTE_OPTION_LEN == options->optionLength)
{
- memcpy(&(optValue->srcGw), options->optionData + count, GATEWAY_ID_LENGTH);
- count += GATEWAY_ID_LENGTH;
+ OIC_LOG(INFO, RM_TAG, "No source and destination are present");
+ }
+ else
+ {
+ uint8_t dLen = 0 ;
+ uint16_t count = DEFAULT_ROUTE_OPTION_LEN;
+ memcpy(&dLen, options->optionData + count, sizeof(dLen));
+ count += sizeof(dLen);
+ if (0 < dLen)
+ {
+ memcpy(&(optValue->destGw), options->optionData + count, GATEWAY_ID_LENGTH);
+ count += GATEWAY_ID_LENGTH;
+
+ if (GATEWAY_ID_LENGTH < dLen)
+ {
+ memcpy(&(optValue->destEp), options->optionData + count, ENDPOINT_ID_LENGTH);
+ count += ENDPOINT_ID_LENGTH;
+ }
+ }
- if (GATEWAY_ID_LENGTH < sLen)
+ uint8_t sLen = 0;
+ memcpy(&sLen, options->optionData + count, sizeof(sLen));
+ count += sizeof(sLen);
+ if (0 < sLen)
{
- memcpy(&(optValue->srcEp), options->optionData + count, ENDPOINT_ID_LENGTH);
- count += ENDPOINT_ID_LENGTH;
+ memcpy(&(optValue->srcGw), options->optionData + count, GATEWAY_ID_LENGTH);
+ count += GATEWAY_ID_LENGTH;
+
+ if (GATEWAY_ID_LENGTH < sLen)
+ {
+ memcpy(&(optValue->srcEp), options->optionData + count, ENDPOINT_ID_LENGTH);
+ count += ENDPOINT_ID_LENGTH;
+ }
}
+ memcpy(&optValue->mSeqNum, options->optionData + count, sizeof(optValue->mSeqNum));
}
- memcpy(&optValue->mSeqNum, options->optionData + count, sizeof(optValue->mSeqNum));
- count += sizeof(optValue->mSeqNum);
- memcpy(&optValue->msgType, options->optionData + count, sizeof(optValue->msgType));
OIC_LOG_V(INFO, RM_TAG, "Option hopcount is %d", optValue->mSeqNum);
OIC_LOG_V(INFO, RM_TAG, "Option Sender Addr is [%u][%u]", optValue->srcGw, optValue->srcEp);
OCSRM_SRC + 'svcresource.c',
OCSRM_SRC + 'pconfresource.c',
OCSRM_SRC + 'dpairingresource.c',
+ OCSRM_SRC + 'verresource.c',
OCSRM_SRC + 'policyengine.c',
OCSRM_SRC + 'psinterface.c',
OCSRM_SRC + 'srmresourcestrings.c',
OCSRM_SRC + 'pconfresource.c',
OCSRM_SRC + 'dpairingresource.c',
OCSRM_SRC + 'policyengine.c',
+ OCSRM_SRC + 'verresource.c',
OCSRM_SRC + 'psinterface.c',
OCSRM_SRC + 'srmresourcestrings.c',
OCSRM_SRC + 'srmutility.c',
if target_os in ['linux', 'android', 'tizen'] and env.get('SECURED') == '1':
SConscript('provisioning/SConscript')
+if target_os in ['linux'] and env.get('SECURED') == '1':
+ SConscript('tool/SConscript')
- /******************************************************************
- *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef _IOTVT_B64_H_
#define _IOTVT_B64_H_
#define B64DECODE_OUT_SAFESIZE(x) (((x)*3)/4)
/**
- * Result code of base64 functions
+ * Result code of base64 functions.
*/
-typedef enum {
+typedef enum
+{
B64_OK = 0,
B64_INVALID_PARAM,
B64_OUTPUT_BUFFER_TOO_SMALL,
B64_ERROR
-}B64Result;
+} B64Result;
/**
* Encode the plain message in base64.
*
- * @param[in] in Plain message
- * @param[in] inLen Byte length of 'in'
- * @param[in,out] outBuf Output buffer
- * Base64 encoded message will be written into 'outBuf'
- * NOTE : This method adds a NULL to the string configuration
- * @param[in] outBufSize Size of output buffer
- * @param[out] outLen Byte length of encoded message
+ * @param in is the plain message to be converted.
+ * @param inLen is the byte length of plain message.
+ * @param outBuf is the output buffer containing Base64 encoded message.
+ * @note outBuf adds a NULL to the string configuration.
+ * @param outBufSize is the size of output buffer.
+ * @param outLen is the byte length of encoded message.
*
- * @return B64_OK for Success, otherwise some error value
+ * @return ::B64_OK for Success, otherwise some error value.
*/
B64Result b64Encode(const uint8_t* in, const size_t inLen,
char* outBuf, const size_t outBufSize, uint32_t *outLen);
/**
* Decode the encoded message in base64.
*
- * @param[in] in Base64 encoded message
- * @param[in] inLen Byte lenth of 'in'
- * @param[in, out] outBuf Output buffer
- * Base64 decoded message will be written into 'outBuf'
- * @param[in] outBufSize Size of output buffer
- * @param[out] outLen Byte length of decoded message
+ * @param in is the Base64 encoded message to be converted.
+ * @param inLen is the byte length of the encoded message.
+ * @param outBuf is the output buffer containing decoded message.
+ * @note outBuf adds a NULL to the string configuration.
+ * @param outBufSize is the size of output buffer.
+ * @param outLen is the byte length of decoded message.
*
- * @return B64_OK for Success, otherwise some error value
+ * @return ::B64_OK for Success, otherwise some error value.
*/
B64Result b64Decode(const char* in, const size_t inLen,
uint8_t* outBuf, size_t outBufSize, uint32_t *outLen);
/**
* Initialize ACL resource by loading data from persistent storage.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult InitACLResource();
/**
* Perform cleanup for ACL resources.
*
- * @retval none
*/
-void DeInitACLResource();
+OCStackResult DeInitACLResource();
/**
* This method is used by PolicyEngine to retrieve ACL for a Subject.
* @param savePtr is used internally by @ref GetACLResourceData to maintain index between
* successive calls for same subjectId.
*
- * @retval reference to @ref OicSecAcl_t if ACL is found, else NULL
+ * @note On the first call to @ref GetACLResourceData, savePtr should point to NULL.
*
- * @note On the first call to @ref GetACLResourceData, savePtr should point to NULL
+ * @return reference to @ref OicSecAcl_t if ACL is found, else NULL.
*/
const OicSecAcl_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAcl_t **savePtr);
/**
- * This function converts ACL data into JSON format.
- * Caller needs to invoke 'free' when done using
- * returned string.
- * @param acl instance of OicSecAcl_t structure.
+ * This function converts ACL data into CBOR format.
*
- * @retval pointer to ACL in json format.
+ * @param acl instance of @ref OicSecAcl_t structure.
+ * @param outPayload is the pointer to allocated memory for cbor payload.
+ * @param size of the cbor payload.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
-char* BinToAclJSON(const OicSecAcl_t * acl);
-
+OCStackResult AclToCBORPayload(const OicSecAcl_t * acl, uint8_t **outPayload, size_t *size);
/**
* This function deletes ACL data.
*
- * @param acl instance of OicSecAcl_t structure.
+ * @param acl instance of @ref OicSecAcl_t structure to be deleted.
*/
void DeleteACLList(OicSecAcl_t* acl);
-
/**
* This function installs a new ACL.
- * @param newJsonStr JSON string representing a new ACL.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @param payload cbor value representing a new ACL.
+ * @param size of the cbor payload.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value
*/
-OCStackResult InstallNewACL(const char* newJsonStr);
+OCStackResult InstallNewACL(const uint8_t* payload, const size_t size);
/**
* This function updates default ACL which is required for ownership transfer.
*/
OCStackResult UpdateDefaultSecProvACL();
+/**
+ * Internal function to update resource owner
+ *
+ * @param newROwner new owner
+ *
+ * @retval ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SetAclRownerId(const OicUuid_t* newROwner);
+
+
+/**
+ * Gets the OicUuid_t value for the rownerid of the acl resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetAclRownerId(OicUuid_t *rowneruuid);
+
#ifdef __cplusplus
}
#endif
/**
* Initialize Amacl resource by loading data from persistent storage.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult InitAmaclResource();
/**
* Perform cleanup for Amacl resources.
- *
- * @retval none
*/
void DeInitAmaclResource();
* If the Amacl is found for the given resource then populate the parameter
* amsId with Amacl resource amss id.
*
- * @param resource resource for which AMS service is required.
- * @param amsId ID of the ams service for the given resource
- *
- * @retval
- * OC_STACK_OK If Amacl found for the resource
- * OC_STACK_ERROR If no Amacl found for the resource
+ * @param resource for which AMS service is required.
+ * @param amsId of the ams service for the given resource.
*
+ * @return ::OC_STACK_OK, if Amacl is found for the resource, else ::OC_STACK_ERROR,
+ * if no Amacl found for the resource.
*/
OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsId);
/**
- * This function converts Amacl data into JSON format.
- * Caller needs to invoke 'free' when done using
- * returned string.
- * @param Amacl instance of OicSecAmacl_t structure.
+ * This function converts Amacl data into CBOR format.
+ * Caller needs to invoke 'free' when done using returned string.
+ *
+ * @param amacl instance of @ref OicSecAmacl_t structure.
+ * @param cborPayload is the converted cbor value of @ref OicSecAmacl_t structure.
+ * @param cborSize is the size of the cbor payload. This value is the size of the
+ * cborPayload. It should not be NON-NULL value.
+ *
+ * @return ::OC_STACK_OK for Success. ::OC_STACK_INVALID in case of invalid parameters.
+ * ::OC_STACK_ERROR in case of error in converting to cbor.
+ */
+OCStackResult AmaclToCBORPayload(const OicSecAmacl_t *amacl, uint8_t **cborPayload,
+ size_t *cborSize);
+
+/**
+ * Internal function to update resource owner
*
- * @retval pointer to Amacl in json format.
+ * @param newROwner new owner
+ *
+ * @retval ::OC_STACK_OK for Success, otherwise some error value
*/
-char* BinToAmaclJSON(const OicSecAmacl_t * amacl);
+OCStackResult SetAmaclRownerId(const OicUuid_t* newROwner);
+
+/**
+ * Gets the OicUuid_t value for the rownerid of the amacl resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetAmaclRownerId(OicUuid_t *rowneruuid);
#ifdef __cplusplus
}
#endif
#endif //IOTVT_SRM_AMACLR_H
-
-
#ifndef IOTVT_SRM_AMSMGR_H
#define IOTVT_SRM_AMSMGR_H
+#include <stdlib.h>
+#include <stdint.h>
+
#include "ocstack.h"
#include "logger.h"
#include "policyengine.h"
#include "securevirtualresourcetypes.h"
#include "cainterface.h"
-#include <stdlib.h>
-#include <stdint.h>
typedef struct PEContext PEContext_t;
/**
- * @brief The AMS context..
+ * The AMS context.
*/
typedef struct AmsMgrContext
{
CARequestInfo_t *requestInfo;
} AmsMgrContext_t;
-
/**
- * @brief This method updates AmsMgr context's endpoint & requestInfo
+ * This method updates AmsMgr context's endpoint & requestInfo.
+ *
+ * @param context is the policy engine context.
+ * @param endpoint is the CA Endpoint info of the requester.
+ * @param requestInfo is the CA RequestInfo of the requester.
*
- * @param context Policy engine context.
- * @param endpoint CA Endpoint info of the requester
- * @param requestInfo CA RequestInfo of the requester
+ * @return ::OC_STACK_OK if successful, else other value in case of error.
*/
-OCStackResult UpdateAmsMgrContext(PEContext_t *context, const CAEndpoint_t *endpoint,
- const CARequestInfo_t *requestInfo);
+OCStackResult UpdateAmsMgrContext(PEContext_t *context,
+ const CAEndpoint_t *endpoint,
+ const CARequestInfo_t *requestInfo);
/**
- *
* This method is called by PolicyEngine to Discover AMS service.
* It sends muticast discovery request such as
* /oic/sec/doxm?deviceid="AMSSrvcDeviceID" to discover AMS service
- * with deviceId="AMSSrvcDeviceID"
- *
- * @param context Policy engine context.
+ * with deviceId="AMSSrvcDeviceID".
*
- * @retval
- * OC_STACK_OK If able to successfully send multicast discovery request.
- * OC_STACK_ERROR If unable to successfully send multicast discovery request due to error.
+ * @param context is the policy engine context.
*
+ * @return ::OC_STACK_OK,If able to successfully send multicast discovery request.
+ * else ::OC_STACK_ERROR, If unable to successfully send multicast discovery request
+ * due to error.
*/
OCStackResult DiscoverAmsService(PEContext_t *context);
-
/**
- *
* This method sends unicast request to retrieve the secured port info of the
* discovered AMS service. It sends unicast discovery request such as
- * /oic/res?rt="oic.sec.doxm" to the discovered AMS service
- *
- * @param context Policy engine context.
+ * /oic/res?rt="oic.sec.doxm" to the discovered AMS service.
*
- * @retval
- * OC_STACK_OK If able to successfully send unicast discovery request
- * OC_STACK_ERROR If unable to successfully send unicast discovery request due to error
+ * @param context is the policy engine context.
*
+ * @return ::OC_STACK_OK,If able to successfully send unicast discovery request.
+ * else ::OC_STACK_ERROR, If unable to successfully send unicast discovery request
+ * due to error.
*/
-OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,OCDevAddr *devAddr,
- OCConnectivityType connType);
-
+OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,
+ OCDevAddr *devAddr,
+ OCConnectivityType connType);
/**
- *
* This method sends unicast request to AMS service to get ACL for
* the Subject and/or Resource. It sends unicast request such as
* /oic/sec/acl?sub="subjectId";rsrc="/a/led" to get the ACL for
- * the subject & resource
+ * the subject & resource.
*
- * @param context Policy engine context.
+ * @param context is the policy engine context.
*
- * @retval
- * OC_STACK_OK If able to successfully send unicast ACL request
- * OC_STACK_ERROR If unable to successfully send unicast ACL request due to error
+ * @return ::OC_STACK_OK, If able to successfully send unicast ACL request.
+ * ::OC_STACK_ERROR, If unable to successfully send unicast ACL request due to error.
*
*/
-OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType,
- uint16_t securedPort);
+OCStackResult SendAclReq(PEContext_t *context,
+ OCDevAddr *devAddr,
+ OCConnectivityType connType,
+ uint16_t securedPort);
/*
* This method is used by Policy engine to checks Amacl resource.
* If Amacl is found then it fills up context->amsMgrContext->amsDeviceId
* with amsID of the Amacl else leaves it empty.
*
- * @param context Policy engine context.
+ * @param context is the policy engine context.
*
- * @return true if AMacl for the resource is found
- * false if AMacl for the resource is not found
+ * @return true, if Amacl for the resource is found. false, if Amacl for the
+ * resource is not found
*/
bool FoundAmaclForRequest(PEContext_t *context);
-
/*
- * This method is used by Policy engine to process AMS request
- *
- * @param context Policy engine context.
+ * This method is used by Policy engine to process AMS request.
*
+ * @param context is the policy engine context.
*/
void ProcessAMSRequest(PEContext_t *context);
-
/*
- * This method is used by Policy engine to free AMS context requestInfo
- *
- * @param requestInfo pointer to CARequestInfo_t.
+ * This method is used by Policy engine to free AMS context requestInfo/
*
+ * @param requestInfo is the pointer to @ref CARequestInfo_t.
*/
void FreeCARequestInfo(CARequestInfo_t *requestInfo);
/**
* Initialize credential resource by loading data from persistent storage.
*
- * @retval
- * OC_STACK_OK - no errors
- * OC_STACK_ERROR - stack process error
+ * @return ::OC_STACK_OK, if initialization is successful, else ::OC_STACK_ERROR if
+ * initialization fails.
*/
OCStackResult InitCredResource();
/**
* Perform cleanup for credential resources.
*
- * @retval
- * OC_STACK_OK - no errors
- * OC_STACK_ERROR - stack process error
- * OC_STACK_NO_RESOURCE - resource not found
- * OC_STACK_INVALID_PARAM - invalid param
+ * @return ::OC_STACK_OK, if no errors. ::OC_STACK_ERROR, if stack process error.
+ * ::OC_STACK_NO_RESOURCE, if resource not found.
+ * ::OC_STACK_INVALID_PARAM, if invalid param.
*/
OCStackResult DeInitCredResource();
/**
- * This method is used by tinydtls/SRM to retrieve credential for given Subject.
+ * This method is used by tinydtls/SRM to retrieve credential for given subject.
*
- * @param subject - subject for which credential is required.
+ * @param subjectId for which credential is required.
*
- * @retval
- * reference to OicSecCred_t - if credential is found
- * NULL - if credential not found
+ * @return reference to @ref OicSecCred_t, if credential is found, else NULL, if credential
+ * not found.
*/
const OicSecCred_t* GetCredResourceData(const OicUuid_t* subjectId);
/**
- * This function converts credential data into JSON format.
- * Caller needs to invoke 'free' when done using
- * returned string.
- * @param cred pointer to instance of OicSecCred_t structure.
- *
- * @retval
- * pointer to JSON credential representation - if credential for subjectId found
- * NULL - if credential for subjectId not found
+ * This function converts credential data into CBOR format.
+ * Caller needs to invoke 'free' when done using returned string.
+ *
+ * @param cred is the pointer to instance of OicSecCred_t structure.
+ * @param cborPayload is the CBOR converted value.
+ * @param cborSize is the size of the CBOR.
+ *
+ * @return ::OC_STACK_OK if conversion is successful, else ::OC_STACK_ERROR if unsuccessful.
*/
-char* BinToCredJSON(const OicSecCred_t* cred);
+OCStackResult CredToCBORPayload(const OicSecCred_t* cred, uint8_t **cborPayload,
+ size_t *cborSize);
/**
* This function generates the bin credential data.
* @param credType credential type.
* @param publicData public data such as public key.
* @param privateData private data such as private key.
- * @param ownersLen length of owners array
- * @param owners array of owners.
+ * @param rownerID Resource owner's UUID.
*
- * @retval
- * pointer to instance of OicSecCred_t - success
- * NULL - error
+ * @return pointer to instance of @ref OicSecCred_t if successful. else NULL in case of error.
+
*/
OicSecCred_t * GenerateCredential(const OicUuid_t* subject, OicSecCredType_t credType,
- const char * publicData, const char * privateData, size_t ownersLen,
- const OicUuid_t * owners);
+ const OicSecCert_t * publicData, const OicSecKey_t * privateData,
+ const OicUuid_t * rownerID);
/**
* This function adds the new cred to the credential list.
*
- * @param cred pointer to new credential.
+ * @param cred is the pointer to new credential.
*
- * @retval
- * OC_STACK_OK - cred not NULL and persistent storage gets updated
- * OC_STACK_ERROR - cred is NULL or fails to update persistent storage
+ * @return ::OC_STACK_OK, cred not NULL and persistent storage gets updated.
+ * ::OC_STACK_ERROR, cred is NULL or fails to update persistent storage.
*/
OCStackResult AddCredential(OicSecCred_t * cred);
/**
* Function to remove the credential from SVR DB.
*
- * @param credId Credential ID to be deleted.
+ * @param credId is the Credential ID to be deleted.
*
- * @return OC_STACK_OK for success and errorcode otherwise.
+ * @return ::OC_STACK_OK for success, or errorcode otherwise.
*/
-OCStackResult RemoveCredential(const OicUuid_t* credId);
-
-/**
- * Remove all credential data on credential resource and persistent storage
- *
- * @retval
- * OC_STACK_OK - no errors
- * OC_STACK_ERROR - stack process error
- */
-OCStackResult RemoveAllCredentials(void);
+OCStackResult RemoveCredential(const OicUuid_t *credId);
#if defined(__WITH_DTLS__)
/**
* This internal callback is used by lower stack (i.e. CA layer) to
* retrieve PSK credentials from RI security layer.
*
- * @param[in] type type of PSK data required by CA layer during DTLS handshake.
- * @param[in] desc Additional request information.
- * @param[in] desc_len The actual length of desc.
- * @param[out] result Must be filled with the requested information.
- * @param[in] result_length Maximum size of @p result.
+ * @param type of PSK data required by CA layer during DTLS handshake.
+ * @param desc Additional request information.
+ * @param desc_len is the actual length of desc.
+ * @param result is must be filled with the requested information.
+ * @param result_length is the maximum size of @p result.
*
* @return The number of bytes written to @p result or a value
* less than zero on error.
unsigned char *result, size_t result_length);
/**
- * Add temporal PSK to PIN based OxM
+ * Add temporal PSK to PIN based OxM.
*
- * @param[in] tmpSubject UUID of target device
- * @param[in] credType Type of credential to be added
- * @param[in] pin numeric characters
- * @param[in] pinSize length of 'pin'
- * @param[in] ownersLen Number of owners
- * @param[in] owners Array of owners
- * @param[out] tmpCredSubject Generated credential's subject.
+ * @param tmpSubject is the UUID of target device
+ * @param credType is the type of credential to be added
+ * @param pin is the numeric characters
+ * @param pinSize is the length of 'pin'
+ * @param rownerID Resource owner's UUID
+ * @param tmpCredSubject is the generated credential's subject.
*
- * @return OC_STACK_OK for success and errorcode otherwise.
+ * @return ::OC_STACK_OK for success or else errorcode.
*/
OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
const char * pin, size_t pinSize,
- size_t ownersLen, const OicUuid_t * owners, OicUuid_t* tmpCredSubject);
+ const OicUuid_t * rownerID,
+ OicUuid_t* tmpCredSubject);
#endif /* __WITH_DTLS__ */
/**
* This function is used toretrieve certificate credentials from RI security layer.
*
- * @param credInfo
- * binary structure containing certificate credentials
+ * @param credInfo is the binary structure containing certificate credentials
*
- * @retval 0 on scuccess
+ * @return 0 on success.
*/
int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo);
#endif /*__WITH_X509__*/
/**
- * Function to deallocate allocated memory to OicSecCred_t
+ * Function to deallocate allocated memory to OicSecCred_t.
*
- * @param cred pointer to cred type
+ * @param cred pointer to cred type.
*
*/
void DeleteCredList(OicSecCred_t* cred);
+/**
+ * Internal function to update resource owner
+ *
+ * @param newROwner new owner
+ *
+ * @retval ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SetCredRownerId(const OicUuid_t* newROwner);
+
+/**
+ * Gets the OicUuid_t value for the rownerid of the cred resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetCredRownerId(OicUuid_t *rowneruuid);
+
#ifdef __cplusplus
}
#endif
#endif //IOTVT_SRM_CREDR_H
-
-
#endif
/**
- * This function stores CRL in SRM
- * @param crl - CRL
+ * This function stores CRL in SRM.
*
- * @returns OC_STACK_OK for Success, otherwise some error value
+ * @param crl to be stored in SRM.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult UpdateCRLResource(const OicSecCrl_t *crl);
/**
- * This function get encoded with base64 CRL from SRM
+ * This function get encoded with base64 CRL from SRM.
+ *
+ * @note Caller responsible for resulting string memory (use OICFree to remove it).
*
- * @returns encoded CRL with base64 format. NULL if error occured (e.g. CRL did not set)
- * @note Caller responsible for resulting string memory (use OICFree to remove it)
+ * @return NULL if error occured (e.g. CRL did not set).
*/
-char* GetBase64CRL();
+uint8_t* GetCrl();
+
/**
- * This function get encoded with DER CRL from SRM
+ * This function get encoded with DER CRL from SRM.
*
- * @returns encoded CRL with DER format. array len is 0 if error occured (e.g. CRL did not set)
+ * @return encoded CRL with DER format. array len is 0 if error occured (e.g. CRL did not set).
*/
void GetDerCrl(ByteArray crlArray);
/**
- * This function get CRL from SRM
+ * This function converts CRL to CBOR
*
- * @param crl [out] - pointer to buffer that contains crl. Shoul be not NULL. Buffer
+ * @param crl is a pointer to buffer that contains crl. Shoul be not NULL. Buffer
* will be allocated by the function and content of *crl will be ignored.
- * @param outlen [out] - pointer to length of the CRL buffer. Shoul be not NULL.
+ * @param payload is the converted cbor value.
+ * @param size is a pointer to length of the CRL buffer. Should be not NULL.
+ *
+ * @note Caller responsible for crl buffer memory (use OICFree to free it).
*
- * @returns OC_STACK_OK if success and errorcode otherwise.
- * @note Caller responsible for crl buffer memory (use OICFree to free it)
+ * @return ::OC_STACK_OK if success, otherwise some error value.
*/
-OicSecCrl_t * JSONToCrlBin(const char * jsonStr);
+OCStackResult CrlToCBORPayload(const OicSecCrl_t *crl, uint8_t **payload, size_t *size);
/**
- * Initialize CLR resource by loading data from persistent storage.
+ * This function converts CBOR to CRL
*
- * @returns OC_STACK_OK for Success, otherwise some error value
+ * will be allocated by the function and content of *crl will be ignored.
+ * @param cborPayload is the cbor vlaue
+ * @param size is a pointer to length of the CRL buffer. Should be not NULL.
+ * @param crl is a pointer to buffer that contains crl. Shoul be not NULL. Buffer
+ *
+ * @note Caller responsible for crl buffer memory (use OICFree to free it).
+ *
+ * @return ::OC_STACK_OK if success, otherwise some error value.
+ */
+OCStackResult CBORPayloadToCrl(const uint8_t *cborPayload, const size_t size,
+ OicSecCrl_t **secCrl);
+/**
+ * Initialize CRL resource by loading data from persistent storage.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult InitCRLResource();
*/
void DeInitCRLResource();
+/**
+ * Get an instance of CRL resource.
+ *
+ * @return reference to the @ref OicSecCrl_t, holding reference to CRL resource.
+ */
OicSecCrl_t *GetCRLResource();
-OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest,
- void* callbackParameter);
#ifdef __cplusplus
}
#endif
#endif //IOTVT_SRM_CRLR_H
-
-
/**
* Initialize DOXM resource by loading data from persistent storage.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult InitDoxmResource();
/**
* Perform cleanup for DOXM resources.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult DeInitDoxmResource();
/**
* This method is used by SRM to retrieve DOXM resource data..
*
- * @retval reference to @ref OicSecDoxm_t, binary format of Doxm resource data
+ * @return reference to @ref OicSecDoxm_t, binary format of Doxm resource data.
*/
const OicSecDoxm_t* GetDoxmResourceData();
/**
- * This method converts JSON DOXM into binary DOXM.
- * The JSON DOXM can be from persistent database or
+ * This method converts CBOR DOXM into binary DOXM.
+ * The CBOR DOXM can be from persistent database or
* or received as PUT/POST request.
*
- * @param[in] jsonStr doxm data in json string.
- * @return pointer to OicSecDoxm_t.
+ * @param cborPayload is a doxm data in cbor.
+ * @note Caller needs to invoke OCFree after done using the return pointer.
+ * @param doxm is the pointer to @ref OicSecDoxm_t.
+ * @param size of the cborPayload. In case value is 0, CBOR_SIZE value is assigned.
*
- * @note Caller needs to invoke OCFree after done
- * using the return pointer
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
-OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr);
+OCStackResult CBORPayloadToDoxm(const uint8_t *cborPayload, size_t size,
+ OicSecDoxm_t **doxm);
/**
- * This method converts DOXM data into JSON format.
+ * This method converts DOXM data into CBOR format.
* Caller needs to invoke 'free' when finished done using
- * return string
+ * return string.
*
- * @param[in] doxm Pointer to OicSecDoxm_t.
- * @return pointer to json string.
+ * @param doxm Pointer to @ref OicSecDoxm_t.
+ * @note Caller needs to invoke OCFree after done using the return pointer.
+ * @param cborPayload is the payload of the cbor.
+ * @param cborSize is the size of the cbor payload. Passed parameter should not be NULL.
*
- * @note Caller needs to invoke OCFree after done
- * using the return pointer
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
-char * BinToDoxmJSON(const OicSecDoxm_t * doxm);
+OCStackResult DoxmToCBORPayload(const OicSecDoxm_t * doxm, uint8_t **cborPayload,
+ size_t *cborSize);
/**
* This method returns the SRM device ID for this device.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult GetDoxmDeviceID(OicUuid_t *deviceID);
/**
- * @brief Gets the OicUuid_t value for the owner of this device.
+ * Gets the OicUuid_t value for the owner of this device.
*
- * @return OC_STACK_OK if devOwner is a valid UUID, otherwise OC_STACK_ERROR.
+ * @param devownerid a pointer to be assigned to the devownerid property
+ * @return ::OC_STACK_OK if devownerid is assigned correctly, else ::OC_STACK_ERROR.
*/
-OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner);
+OCStackResult GetDoxmDevOwnerId(OicUuid_t *devownerid);
+
+/**
+ * Gets the OicUuid_t value for the rowneruuid of the doxm resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid);
/** This function deallocates the memory for OicSecDoxm_t .
*
- * @param[in] doxm Pointer to OicSecDoxm_t.
+ * @param doxm is the pointer to @ref OicSecDoxm_t.
*/
void DeleteDoxmBinData(OicSecDoxm_t* doxm);
#endif
#endif //IOTVT_SRM_DOXMR_H
-
-
OCStackResult DeInitDpairingResource();\r
\r
/**\r
- * This method converts JSON DPAIRING into binary DPAIRING.\r
- * The JSON DPAIRING can be from persistent database or\r
+ * This method converts CBOR DPAIRING into binary DPAIRING.\r
+ * The CBOR DPAIRING can be from persistent database or\r
* or received as POST request.\r
*\r
- * @param[in] jsonStr pconf data in json string.\r
- * @return pointer to OicSecDpairing_t.\r
+ * @param cborPayload pconf data in cbor format.\r
+ * @param size size of the cbor payload\r
+ * @param secDpair binary Dpairing resource\r
+ * @return OC_STACK_OK for Success, otherwise some error value.\r
*\r
- * @note Caller needs to invoke OCFree after done\r
+ * @note Caller needs to invoke OICFree after done\r
* using the return pointer\r
*/\r
-OicSecDpairing_t * JSONToDpairingBin(const char * jsonStr);\r
+OCStackResult CBORPayloadToDpair(const uint8_t *cborPayload, size_t size,\r
+ OicSecDpairing_t **secDpair);\r
\r
/**\r
- * This method converts DPAIRING data into JSON format.\r
- * Caller needs to invoke 'free' when finished done using\r
- * return string\r
+ * This method converts DPAIRING data into CBOR format.\r
*\r
- * @param[in] dpair Pointer to OicSecDpairing_t.\r
- * @return pointer to json string.\r
+ * @param dpair Pointer to OicSecDpairing_t.\r
+ * @param payload CBOR format converted from binary dpairing\r
+ * @param size Size of the coverted payload\r
+ * @return OC_STACK_OK for Success, otherwise some error value.\r
*\r
- * @note Caller needs to invoke OCFree after done\r
+ * @note Caller needs to invoke OICFree after done\r
* using the return pointer\r
*/\r
-char * BinToDpairingJSON(const OicSecDpairing_t * dpair);\r
+OCStackResult DpairingToCBORPayload(const OicSecDpairing_t *dpair, uint8_t **payload, size_t *size);\r
\r
/** This function deallocates the memory for OicSecPconf_t .\r
*\r
OicUuid_t *peerDevID, OicUuid_t *owner, bool isPairingServer);\r
#endif // __WITH_DTLS__\r
\r
+/**\r
+ * Gets the OicUuid_t value for the rownerid of the Dpairing resource.\r
+ *\r
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property\r
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.\r
+ */\r
+OCStackResult GetDpairingRownerId(OicUuid_t *rowneruuid);\r
+\r
+/**\r
+ * Internal function to update resource owner\r
+ *\r
+ * @param newROwner new owner\r
+ *\r
+ * @retval ::OC_STACK_OK for Success, otherwise some error value\r
+ */\r
+OCStackResult SetDpairingRownerId(const OicUuid_t* newROwner);\r
\r
#ifdef __cplusplus\r
}\r
const OicSecPconf_t* GetPconfResourceData();\r
\r
/**\r
- * This method converts JSON PCONF into binary PCONF.\r
+ * This method converts CBOR PCONF into binary PCONF.\r
* The JSON PCONF can be from persistent database or\r
* or received as PUT request.\r
*\r
- * @param[in] jsonStr pconf data in json string.\r
- * @return pointer to OicSecPconf_t.\r
+ * @param cborPayload pconf data in cbor format.\r
+ * @param size cbor payload size\r
+ * @param secPconf converted pconf\r
+ * @return OC_STACK_OK for success.\r
*\r
* @note Caller needs to invoke OCFree after done\r
* using the return pointer\r
*/\r
-OicSecPconf_t * JSONToPconfBin(const char * jsonStr);\r
+OCStackResult CBORPayloadToPconf(const uint8_t *cborPayload, size_t size, OicSecPconf_t **secPconf);\r
\r
/**\r
- * This method converts PCONF data into JSON format.\r
+ * This method converts PCONF data into CBOR format.\r
* Caller needs to invoke 'free' when finished done using\r
* return string\r
*\r
- * @param[in] pconf Pointer to OicSecPconf_t.\r
- * @return pointer to json string.\r
+ * @param pconf Pointer to OicSecPconf_t.\r
+ * @param payload pconf converted in cbor format\r
+ * @param size size of the converted payload\r
+ * @return OC_STACK_OK for success.\r
*\r
* @note Caller needs to invoke OCFree after done\r
* using the return pointer\r
*/\r
-char * BinToPconfJSON(const OicSecPconf_t * pconf);\r
+OCStackResult PconfToCBORPayload(const OicSecPconf_t *pconf,uint8_t **payload,size_t *size);\r
\r
/**\r
* This method might be used to add a paired device id after direct-pairing process complete.\r
*/\r
void FreePdAclList(OicSecPdAcl_t* pdacls);\r
\r
+/**\r
+ * Internal function to update resource owner\r
+ *\r
+ * @param newROwner new owner\r
+ *\r
+ * @retval ::OC_STACK_OK for Success, otherwise some error value\r
+ */\r
+OCStackResult SetPconfRownerId(const OicUuid_t* newROwner);\r
+\r
+/**\r
+ * Gets the OicUuid_t value for the rownerid of the pconf resource.\r
+ *\r
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property\r
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.\r
+ */\r
+OCStackResult GetPconfRownerId(OicUuid_t *rowneruuid);\r
\r
#ifdef __cplusplus\r
}\r
typedef struct AmsMgrContext AmsMgrContext_t;
-
typedef enum PEState
{
STOPPED = 0, //Policy engine state machine is not running
BUSY //Can't process new request as processing other requests
} PEState_t;
-
typedef struct PEContext
{
PEState_t state;
OicUuid_t subject;
char resource[MAX_URI_LENGTH];
+ OicSecSvrType_t resourceType;
uint16_t permission;
bool matchingAclFound;
bool amsProcessing;
/**
* Check whether a request should be allowed.
*
- * @param context Pointer to Policy Engine context to use.
- * @param subjectId Pointer to Id of the requesting entity.
- * @param resource Pointer to URI of Resource being requested.
- * @param permission Requested permission.
+ * @param context is the pointer to Policy Engine context to use.
+ * @param subjectId is the pointer to Id of the requesting entity.
+ * @param resource is the pointer to URI of Resource being requested.
+ * @param permission is the requested permission.
*
- * @return ACCESS_GRANTED if request should go through,
- * otherwise some flavor of ACCESS_DENIED
+ * @return ::ACCESS_GRANTED if request should go through, otherwise some flavor of ACCESS_DENIED.
*/
SRMAccessResponse_t CheckPermission(
PEContext_t *context,
* Initialize the Policy Engine. Call this before calling CheckPermission().
* TODO Eventually this and DeInit() need to be called from a new
* "SRMInit(SRMContext_t *)" function, TBD after BeachHead.
- * @param context Pointer to Policy Engine context to initialize.
- * @return OC_STACK_OK for Success, otherwise some error value
+ * @param context is the pointer to Policy Engine context to initialize.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult InitPolicyEngine(PEContext_t *context);
/**
* De-Initialize the Policy Engine. Call this before exiting to allow Policy
* Engine to do cleanup on context.
- * @param context Pointer to Policy Engine context to de-initialize.
- * @return none
+ *
+ * @param context is the pointer to Policy Engine context to de-initialize.
*/
void DeInitPolicyEngine(PEContext_t *context);
/**
- * Return the uint16_t CRUDN permission corresponding to passed CAMethod_t.
+ * Get CRUDN permission for a method.
+ *
+ * @param method is CRUDN permission being seeked.
+ *
+ * @return the uint16_t CRUDN permission .
*/
uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method);
-
/*
* This method reset Policy Engine context to default state and update
* it's state to @param state.
*
- * @param context Policy engine context.
- * @param state Set Policy engine state to this.
- *
- * @return none
+ * @param context is the policy engine context.
+ * @param state set Policy engine state to this.
*/
void SetPolicyEngineState(PEContext_t *context, const PEState_t state);
+typedef OCStackResult (*GetSvrRownerId_t)(OicUuid_t *rowner);
+
#endif //IOTVT_SRM_PE_H
#ifndef IOTVT_SRM_PSI_H
#define IOTVT_SRM_PSI_H
+#include "cJSON.h"
+
/**
* Reads the Secure Virtual Database from PS into dynamically allocated
* memory buffer.
* @note Caller of this method MUST use OCFree() method to release memory
* referenced by return value.
*
- * @retval reference to memory buffer containing SVR database.
+ * @return char * reference to memory buffer containing SVR database.
*/
char * GetSVRDatabase();
* @param rsrcName string denoting the SVR name ("acl", "cred", "pstat" etc).
* @param jsonObj JSON object containing the SVR contents.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value
*/
OCStackResult UpdateSVRDatabase(const char* rsrcName, cJSON* jsonObj);
+/**
+ * Reads the Secure Virtual Database from PS
+ *
+ * @note Caller of this method MUST use OCFree() method to release memory
+ * referenced by return value.
+ *
+ * @param rsrcName is the name of the field for which file content are read.
+ if the value is NULL it will send the content of the whole file.
+ * @param data is the pointer to the file contents read from the database.
+ * @param size is the size to the file contents read.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size);
+
+/**
+ * This method converts updates the persistent storage.
+ *
+ * @param rsrcName is the name of the secure resource that will be updated.
+ * @param cborPayload is the pointer holding cbor payload.
+ * @param cborPayload is the size of the cbor payload.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult UpdateSecureResourceInPS(const char* rsrcName, uint8_t* cborPayload, size_t size);
+
#endif //IOTVT_SRM_PSI_H
/**
* Initialize Pstat resource by loading data from persistent storage.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult InitPstatResource();
/**
* Perform cleanup for Pstat resources.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult DeInitPstatResource();
/**
- * This method converts JSON PSTAT into binary PSTAT.
+ * This method converts PSTAT into the cbor payload.
*
- * @param[in] jsonStr pstat data in json string.
- * @return pointer to OicSecPstat_t.
+ * @param pstat pointer to the initialized pstat structure.
+ * @param cborPayload pointer to pstat cbor payload.
+ * @param size of the cbor payload converted. It is 0 in case of error,
+ * else a positive value if succcessful.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
-OicSecPstat_t * JSONToPstatBin(const char * jsonStr);
+ OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **cborPayload,
+ size_t *cborSize);
/**
- * This method converts pstat data into JSON format.
+ * This method converts cbor into PSTAT data.
*
- * @param[in] pstat pstat data in binary format.
- * @return pointer to pstat json string.
+ * @param cborPayload is the pstat data in cbor format.
+ * @param size of the cborPayload. In case 0 is provided it assigns CBOR_SIZE (255) value.
+ * @param pstat pointer to @ref OicSecPstat_t.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
-char * BinToPstatJSON(const OicSecPstat_t * pstat);
+ OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t cborSize,
+ OicSecPstat_t **pstat);
/** This function deallocates the memory for OicSecPstat_t.
*
- * @param[in] pstat Pointer to OicSecPstat_t.
+ * @param pstat is the pointer to @ref OicSecPstat_t.
*/
void DeletePstatBinData(OicSecPstat_t* pstat);
*/
void RestorePstatToInitState();
+/**
+ * Internal function to update resource owner
+ *
+ * @param newROwner new owner
+ *
+ * @retval ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SetPstatRownerId(const OicUuid_t* newROwner);
+
+/**
+ * Gets the OicUuid_t value for the rownerid of the pstat resource.
+ *
+ * @param rowneruuid a pointer to be assigned to the rowneruuid property
+ * @return ::OC_STACK_OK if rowneruuid is assigned correctly, else ::OC_STACK_ERROR.
+ */
+OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid);
+
+/**
+ * This function returns the "isop" status of the device.
+ *
+ * @return true iff pstat.isop == 1, else false
+ */
+bool GetPstatIsop();
+
#ifdef __cplusplus
}
#endif
#endif //IOTVT_SRM_PSTATR_H
-
-
#include "ocstack.h"
#include "securevirtualresourcetypes.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value
*/
OCStackResult InitSecureResources();
/**
* Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value
*/
OCStackResult DestroySecureResources();
*
* @param ehRequest pointer to entity handler request data structure.
* @param ehRet result code from entity handler.
- * @param rspPayload response payload in JSON.
+ * @param cborPayload response payload.
+ * @param size is the cborpayload size
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult SendSRMResponse(const OCEntityHandlerRequest *ehRequest,
- OCEntityHandlerResult ehRet, const char *rspPayload);
+ OCEntityHandlerResult ehRet, uint8_t *cborPayload, size_t size);
-#endif //IOTVT_SRM_RM_H
+#ifdef __cplusplus
+}
+#endif
+#endif //IOTVT_SRM_RM_H
#endif
/**
- * @brief Register Persistent storage callback.
- * @param persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers.
- * @return
- * OC_STACK_OK - No errors; Success
- * OC_STACK_INVALID_PARAM - Invalid parameter
+ * Register Persistent storage callback.
+ *
+ * @param persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers.
+ *
+ * @return ::OC_STACK_OK is no errors and successful. ::OC_STACK_INVALID_PARAM for invalid parameter.
*/
OCStackResult SRMRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler);
/**
- * @brief Get Persistent storage handler pointer.
- * @return
- * The pointer to Persistent Storage callback handler
+ * Get Persistent storage handler pointer.
+ *
+ * @return The pointer to Persistent Storage callback handler.
*/
OCPersistentStorage* SRMGetPersistentStorageHandler();
/**
- * @brief Register request and response callbacks.
- * Requests and responses are delivered in these callbacks.
- * @param reqHandler [IN] Request handler callback ( for GET,PUT ..etc)
- * @param respHandler [IN] Response handler callback.
- * @param errHandler [IN] Error handler callback.
- * @return
- * OC_STACK_OK - No errors; Success
- * OC_STACK_INVALID_PARAM - Invalid parameter
+ * Register request and response callbacks. Requests and responses are delivered in these callbacks.
+ *
+ * @param reqHandler Request handler callback ( for GET,PUT ..etc)
+ * @param respHandler Response handler callback.
+ * @param errHandler Error handler callback.
+ *
+ * @return ::OC_STACK_OK is no errors and successful. ::OC_STACK_INVALID_PARAM for invalid parameter.
*/
OCStackResult SRMRegisterHandler(CARequestCallback reqHandler,
CAResponseCallback respHandler,
CAErrorCallback errHandler);
/**
- * @brief Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
- * @return OC_STACK_OK for Success, otherwise some error value
+ * Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult SRMInitSecureResources();
/**
- * @brief Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
- * @return none
+ * Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
*/
void SRMDeInitSecureResources();
/**
- * @brief Initialize Policy Engine context.
- * @return OC_STACK_OK for Success, otherwise some error value.
+ * Initialize Policy Engine context.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult SRMInitPolicyEngine();
/**
- * @brief Cleanup Policy Engine context.
- * @return none
+ * Cleanup Policy Engine context.
*/
void SRMDeInitPolicyEngine();
/**
- * @brief Provisioning API response callback.
- * @param object[IN] endpoint instance.
- * @param responseInfo[IN] instance of CAResponseInfo_t structure.
+ * Provisioning API response callback.
+ *
+ * @param object endpoint instance.
+ * @param responseInfo instance of CAResponseInfo_t structure.
+ *
* @return true if received response is for provisioning API false otherwise.
*/
typedef bool (*SPResponseCallback) (const CAEndpoint_t *object,
const CAResponseInfo_t *responseInfo);
/**
- * @brief function to register provisoning API's response callback.
+ * Function to register provisoning API's response callback.
+ *
* @param respHandler response handler callback.
*/
void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler);
/**
- * @brief Check the security resource URI.
- * @param uri [IN] Pointers to security resource URI.
- * @return true if the URI is one of security resources, otherwise false.
+ * Check the security resource URI.
+ * @param uri Pointers to security resource URI.
+ * @return true if the URI is one of security resources, otherwise false.
*/
bool SRMIsSecurityResourceURI(const char* uri);
/**
- * @brief Sends Response
+ * Get the resource type from the URI.
+ * @param uri [IN] Pointers to security resource URI.
+ * @return SVR type (note that "NOT_A_SVR_RESOURCE" is returned if not a SVR)
+ */
+OicSecSvrType_t GetSvrTypeFromUri(const char* uri);
+
+/**
+ * Sends Response
* @param resposeVal SRMAccessResponse_t value
* @return NONE
*/
--- /dev/null
+//******************************************************************
+//
+//Copyright 2016 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef IOTVT_SRM_SECURITY_INTERNALS_H
+#define IOTVT_SRM_SECURITY_INTERNALS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+OicSecAcl_t* CBORPayloadToAcl(const uint8_t *payload, const size_t size);
+
+void DeleteACLList(OicSecAcl_t* acl);
+
+/**
+ * This internal method is to retrieve the default ACL.
+ * If SVR database in persistent storage got corrupted or
+ * is not available for some reason, a default ACL is created
+ * which allows user to initiate ACL provisioning again.
+ */
+OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl);
+
+/**
+ * This internal method is the entity handler for ACL resources and
+ * will handle REST request (GET/PUT/POST/DEL) for them.
+ */
+OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest, void* callbackParameter);
+
+OCStackResult SetDefaultACL(OicSecAcl_t *acl);
+
+/**
+ * Converts CBOR payload to SVC.
+ *
+ * @param cborPayload is the svc payload cbor value that neds to be converted.
+ * @param cborSize of the cborPayload. In case size is not known, it is 0.
+ * @param svc is the value that is initialized. It is NULL in case of error.
+ *
+ * @return ::OC_STACK_OK in case successful. ::OC_STACK_INVALID_PARAM if one of
+ * the passed parameter is NULL. ::OC_STACK_ERROR in case of error.
+ */
+OCStackResult CBORPayloadToSVC(const uint8_t *cborPayload, size_t size, OicSecSvc_t **svc);
+
+/**
+ * Deletes the passed initialized reference to @ref OicSecSvc_t.
+ *
+ * @param svc is the reference to be deleted.
+ */
+void DeleteSVCList(OicSecSvc_t* svc);
+
+/**
+ * Create PSTAT resource after default PSTAT initialization is done.
+ */
+OCStackResult CreatePstatResource();
+
+/**
+ * This internal method is the entity handler for PSTAT resources and
+ * will handle REST request (GET/PUT/POST/DEL) for them.
+ */
+OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest);
+
+/**
+ * Converts CBOR payload to AMACL.
+ *
+ * @param cborPayload is the amacl payload cbor value that neds to be converted.
+ * @param cborSize of the cborPayload. In case size is not known, it is 0.
+ * It should be NON-NULL.
+ * @param amacl is the value that is initialized. It is NULL in case of error.
+ */
+OCStackResult CBORPayloadToAmacl(const uint8_t *cborPayload, size_t cborSize,
+ OicSecAmacl_t **amacl);
+
+void DeleteAmaclList(OicSecAmacl_t *amacl);
+
+/**
+ * This internal method is the entity handler for Cred resources
+ * to handle REST request (PUT/POST/DEL)
+ */
+OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void* callbackParameter);
+
+/**
+ * This internal method is used to create '/oic/sec/Cred' resource.
+ */
+OCStackResult CreateCredResource();
+
+/**
+ * This function converts from CBOR format into credential structure .
+ * Caller needs to invoke 'free' for allocated structure.
+ *
+ * @param cborPayload is the CBOR value that is assigned to the structure.
+ * @param size is the size of the CBOR.
+ * @param secCred is the pointer to instance of @ref OicSecCred_t structure that will be allocated.
+ * If it fails it will return NULL.
+ *
+ * @return ::OC_STACK_OK if conversion is successful, else ::OC_STACK_ERROR if unsuccessful.
+ */
+OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
+ OicSecCred_t **secCred);
+
+/**
+ * This internal method is used to create '/oic/sec/doxm' resource.
+ */
+OCStackResult CreateDoxmResource();
+
+/**
+ * This internal method is the entity handler for DOXM resources.
+ */
+OCEntityHandlerResult DoxmEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void* callbackParam);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOTVT_SRM_SECURITY_INTERNALS_H
#include "securevirtualresourcetypes.h"
extern const char * SVR_DB_FILE_NAME;
+extern const char * SVR_DB_DAT_FILE_NAME;
extern const char * OIC_MI_DEF;
//AMACL
extern const char * OIC_RSRC_TYPE_SEC_ACL;
extern const char * OIC_RSRC_ACL_URI;
extern const char * OIC_JSON_ACL_NAME;
+extern const char * OIC_JSON_ACLIST_NAME;
+extern const char * OIC_JSON_ACES_NAME;
//PSTAT
extern const char * OIC_RSRC_TYPE_SEC_PSTAT;
extern const char * OIC_RSRC_TYPE_SEC_CRED;
extern const char * OIC_RSRC_CRED_URI;
extern const char * OIC_JSON_CRED_NAME;
+extern const char * OIC_JSON_CREDS_NAME;
//CRL
extern const char * OIC_RSRC_TYPE_SEC_CRL;
extern const char * OIC_RSRC_CRL_URI;
extern const char * OIC_JSON_CRL_NAME;
+//SACL
+extern const char * OIC_RSRC_TYPE_SEC_SACL;
+extern const char * OIC_RSRC_SACL_URI;
+extern const char * OIC_JSON_SACL_NAME;
+
//SVC
extern const char * OIC_RSRC_TYPE_SEC_SVC;
extern const char * OIC_RSRC_SVC_URI;
extern const char * OIC_RSRC_DPAIRING_URI;
extern const char * OIC_JSON_DPAIRING_NAME;
+//version
+extern const char * OIC_RSRC_TYPE_SEC_VER;
+extern const char * OIC_RSRC_VER_URI;
+extern const char * OIC_JSON_VER_NAME;
+
extern const char * OIC_JSON_SUBJECT_NAME;
+extern const char * OIC_JSON_SUBJECTID_NAME;
extern const char * OIC_JSON_RESOURCES_NAME;
extern const char * OIC_JSON_AMSS_NAME;
+extern const char * OIC_JSON_AMS_NAME;
extern const char * OIC_JSON_PERMISSION_NAME;
extern const char * OIC_JSON_OWNERS_NAME;
extern const char * OIC_JSON_OWNER_NAME;
+extern const char * OIC_JSON_DEVOWNERID_NAME;
extern const char * OIC_JSON_OWNED_NAME;
extern const char * OIC_JSON_OXM_NAME;
+extern const char * OIC_JSON_OXMS_NAME;
extern const char * OIC_JSON_OXM_TYPE_NAME;
extern const char * OIC_JSON_OXM_SEL_NAME;
extern const char * OIC_JSON_DEVICE_ID_FORMAT_NAME;
extern const char * OIC_JSON_CREDTYPE_NAME;
extern const char * OIC_JSON_PUBLICDATA_NAME;
extern const char * OIC_JSON_PRIVATEDATA_NAME;
+extern const char * OIC_JSON_PUBDATA_NAME;
+extern const char * OIC_JSON_PRIVDATA_NAME;
+extern const char * OIC_JSON_OPTDATA_NAME;
+extern const char * OIC_JSON_CRMS_NAME;
extern const char * OIC_JSON_PERIOD_NAME;
extern const char * OIC_JSON_PERIODS_NAME;
extern const char * OIC_JSON_RECURRENCES_NAME;
extern const char * OIC_JSON_PRM_NAME;
extern const char * OIC_JSON_SPM_NAME;
extern const char * OIC_JSON_PDEVICE_ID_NAME;
+extern const char * OIC_JSON_RLIST_NAME;
+extern const char * OIC_JSON_HREF_NAME;
+extern const char * OIC_JSON_REL_NAME;
+extern const char * OIC_JSON_RT_NAME;
+extern const char * OIC_JSON_IF_NAME;
+extern const char * OIC_JSON_ROWNERID_NAME;
+extern const char * OIC_JSON_ENCODING_NAME;
+extern const char * OIC_JSON_DATA_NAME;
+extern const char * OIC_JSON_SEC_V_NAME;
+
+extern const char * OIC_JSON_EMPTY_STRING;
extern OicUuid_t WILDCARD_SUBJECT_ID;
+extern OicUuid_t WILDCARD_SUBJECT_B64_ID;
extern size_t WILDCARD_SUBJECT_ID_LEN;
extern const char * WILDCARD_RESOURCE_URI;
extern const char * OXM_RANDOM_DEVICE_PIN;
extern const char * OXM_MANUFACTURER_CERTIFICATE;
+extern const char * OIC_SEC_ENCODING_BASE64;
+extern const char * OIC_SEC_ENCODING_RAW;
+
extern const char * OIC_SEC_TRUE;
extern const char * OIC_SEC_FALSE;
extern const char * OIC_SEC_REST_QUERY_SEPARATOR;
extern char OIC_SEC_REST_QUERY_DELIMETER;
+//Security Version
+extern const char * DEFAULT_SEC_VERSION;
+
#endif //IOTVT_SRM_RSRC_STRINGS_H
/**
* Initialize SVC resource by loading data from persistent storage.
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult InitSVCResource();
/**
* Perform cleanup for SVC resources.
- *
- * @retval none
*/
void DeInitSVCResource();
/**
- * This function converts SVC data into JSON format.
- * Caller needs to invoke 'free' when done using
- * returned string.
- * @param svc instance of OicSecSvc_t structure.
+ * This function converts SVC data into CBOR format.
+ * Caller needs to invoke 'free' when done using returned string.
+ *
+ * @param svc is the instance of @ref OicSecSvc_t structure. In case of NULL it
+ * will return ::OC_STACK_INVALID_PARAM.
+ * @param cborPayload is the converted cbor value of SVC structure.
+ * @param cborSize is the size of the cbor payload. This value is the size of the
+ * cborPayload. It should not be NON-NULL value.
*
- * @retval pointer to SVC in json format.
+ * @return ::OC_STACK_OK for Success. ::OC_STACK_INVALID in case of invalid parameters.
+ * ::OC_STACK_ERROR in case of error in converting to cbor.
*/
-char* BinToSvcJSON(const OicSecSvc_t * svc);
+ OCStackResult SVCToCBORPayload(const OicSecSvc_t *svc, uint8_t **cborPayload,
+ size_t *cborSize);
#ifdef __cplusplus
}
#endif
#endif //IOTVT_SRM_SVCR_H
-
-
--- /dev/null
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
+
+#ifndef IOTVT_SRM_VER_H
+#define IOTVT_SRM_VER_H
+
+#include "octypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize VER resource by loading data from persistent storage.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult InitVerResource();
+
+/**
+ * Perform cleanup for VER resources.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult DeInitVerResource();
+
+/**
+ * This method is used by SRM to retrieve VER resource data..
+ *
+ * @return reference to @ref OicSecDoxm_t, binary format of Doxm resource data.
+ */
+const OicSecVer_t* GetVerResourceData();
+
+/**
+ * This method converts CBOR VER into binary VER.
+ * The CBOR VER can be from persistent database or
+ * or received as PUT/POST request.
+ *
+ * @param cborPayload is a ver data in cbor.
+ * @note Caller needs to invoke OCFree after done using the return pointer.
+ * @param doxm is the pointer to @ref OicSecVer_t.
+ * @param size of the cborPayload. In case value is 0, CBOR_SIZE value is assigned.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult CBORPayloadToVer(const uint8_t *cborPayload, size_t size,
+ OicSecVer_t **ver);
+
+/**
+ * This method converts VER data into CBOR format.
+ * Caller needs to invoke 'free' when finished done using
+ * return string.
+ *
+ * @param ver Pointer to @ref OicSecVer_t.
+ * @note Caller needs to invoke OCFree after done using the return pointer.
+ * @param cborPayload is the payload of the cbor.
+ * @param cborSize is the size of the cbor payload. Passed parameter should not be NULL.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult VerToCBORPayload(const OicSecVer_t * ver, uint8_t **cborPayload,
+ size_t *cborSize);
+
+/**
+ * Get the security version.
+ *
+ * @return the version string of security.
+ */
+const char* GetSecVersion();
+
+/** This function deallocates the memory for OicSecVer_t .
+ *
+ * @param ver is the pointer to @ref OicSecVer_t.
+ */
+void DeleteVerBinData(OicSecVer_t* ver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOTVT_SRM_VER_H
\ No newline at end of file
typedef struct IotvtICalRecur IotvtICalRecur_t;
typedef struct IotvtICalPeriod IotvtICalPeriod_t;
-/*
- * date-time = date "T" time
+/**
+ * date-time = date "T" time.
*
* date = date-value
* date-value = date-fullyear date-month date-mday
*/
typedef struct tm IotvtICalDateTime_t; //c-lang tm date-time struct
-/*
- * Bit mask for weekdays
+/**
+ * Bit mask for weekdays.
*/
typedef enum
{
THURSDAY = (0x1 << 4),
FRIDAY = (0x1 << 5),
SATURDAY = (0x1 << 6)
-}IotvtICalWeekdayBM_t;
+} IotvtICalWeekdayBM_t;
-/*
- * Result code for IotvtICalendar
+/**
+ * Result code for IotvtICalendar.
*/
typedef enum
{
- IOTVTICAL_SUCCESS = 0, //successfully completed operation
- IOTVTICAL_VALID_ACCESS, //access is within allowable time
- IOTVTICAL_INVALID_ACCESS, //access is not within allowable time
- IOTVTICAL_INVALID_PARAMETER, //invalid method parameter
- IOTVTICAL_INVALID_RRULE, //rrule is not well form, missing FREQ
- IOTVTICAL_INVALID_PERIOD, //period is not well form, start-datetime is after end-datetime
- IOTVTICAL_ERROR //encounter error
-}IotvtICalResult_t;
+ IOTVTICAL_SUCCESS = 0, /**< successfully completed operation. */
+ IOTVTICAL_VALID_ACCESS, /**< access is within allowable time. */
+ IOTVTICAL_INVALID_ACCESS, /**< access is not within allowable time. */
+ IOTVTICAL_INVALID_PARAMETER, /**< invalid method parameter. */
+ IOTVTICAL_INVALID_RRULE, /**< rrule is not well form, missing FREQ. */
+ IOTVTICAL_INVALID_PERIOD, /**< period is not well form, start-datetime is after end-datetime. */
+ IOTVTICAL_ERROR /**< encounter error. */
+} IotvtICalResult_t;
-/*
- * Grammar for iCalendar data type PERIOD
+/**
+ * Grammar for iCalendar data type PERIOD.
*
* period = date-time "/" date-time ; start-time / end-time.
* ;The start-time MUST be before the end-time.
};
/*
- * Grammar for iCalendar data type RECUR
+ * Grammar for iCalendar data type RECUR.
*
* recur = "FREQ"=freq *(
* ( ";" "UNTIL" "=" enddate ) /
* @param period string representing period.
* @param recur string representing recurrence rule
*
- * @return IOTVTICAL_VALID_ACCESS -- if the request is within valid time period
- * IOTVTICAL_INVALID_ACCESS -- if the request is not within valid time period
- * IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
- * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
- * IOTVTICAL_INVALID_RRULE -- if rrule string has invalid format
+ * @return ::IOTVTICAL_VALID_ACCESS, if the request is within valid time period
+ * ::IOTVTICAL_INVALID_ACCESS, if the request is not within valid time period
+ * ::IOTVTICAL_INVALID_PARAMETER, if parameter are invalid
+ * ::IOTVTICAL_INVALID_PERIOD, if period string has invalid format
+ * ::IOTVTICAL_INVALID_RRULE, if rrule string has invalid format.
*
*Eg: if(IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(period, recur))
* {
* //Access is not within allowable time.
* }
*/
-IotvtICalResult_t IsRequestWithinValidTime(char *period, char *recur);
+IotvtICalResult_t IsRequestWithinValidTime(const char *period, const char *recur);
/**
- * Parses periodStr and populate struct IotvtICalPeriod_t
+ * Parses periodStr and populate struct IotvtICalPeriod_t.
*
* @param periodStr string to be parsed.
- * @param period IotvtICalPeriod_t struct to be populated.
+ * @param period IotvtICalPeriod_t struct to be populated.
*
- * @return IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
- * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
- * IOTVTICAL_INVALID_SUCCESS -- if no error while parsing
+ * @return ::IOTVTICAL_VALID_ACCESS, if the request is within valid time period
+ * ::IOTVTICAL_INVALID_PARAMETER, if parameter are invalid
+ * ::IOTVTICAL_INVALID_PERIOD, if period string has invalid format
+ * ::IOTVTICAL_INVALID_SUCCESS, if no error while parsing.
*/
IotvtICalResult_t ParsePeriod(const char *periodStr, IotvtICalPeriod_t *period);
/**
- * Parses recurStr and populate struct IotvtICalRecur_t
+ * Parses recurStr and populate struct IotvtICalRecur_t.
*
* @param recurStr string to be parsed.
- * @param recur IotvtICalPeriod_t struct to be populated.
+ * @param recur is the IotvtICalPeriod_t struct to be populated.
*
- * @return IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
- * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
- * IOTVTICAL_INVALID_RRULE -- if rrule string has invalid format
+ * @return ::IOTVTICAL_VALID_ACCESS, if the request is within valid time period
+ * ::IOTVTICAL_INVALID_PARAMETER, if parameter are invalid
+ * ::IOTVTICAL_INVALID_PERIOD, if period string has invalid format
+ * ::IOTVTICAL_INVALID_RRULE, if rrule string has invalid format.
*/
IotvtICalResult_t ParseRecur(const char *recurStr, IotvtICalRecur_t *recur);
-/* *****************************************************************
- *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * *****************************************************************/
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef _PBKDF2_H
#define _PBKDF2_H
* Function to derive cryptographic key from the password. (RFC 2898)
* In this implementation, HMAC with SHA2 is considered as a pseudorandom function
*
- * @param[in] passwd is the master password from which a derived key is generated.
- * @param[in] pLen is the byte size of the passwd.
- * @param[in] salt is a cryptographic salt.
- * @param[in] saltlen is the byte size of the salt.
- * @param[in] iteration is the number of iterations desired.
- * @param[in] keyLen is the desired byte size of the derived key. (should be the same as
+ * @param passwd is the master password from which a derived key is generated.
+ * @param pLen is the byte size of the passwd.
+ * @param salt is a cryptographic salt.
+ * @param saltlen is the byte size of the salt.
+ * @param iteration is the number of iterations desired.
+ * @param keyLen is the desired byte size of the derived key. (should be the same as
* derivedKey size)
- * @param[out] derivedKey is the generated derived key
+ * @param derivedKey is the generated derived key
*
* @return 0 on success
*/
-/* *****************************************************************
- *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * *****************************************************************/
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef PIN_CALLBACK_DEF_H_
#define PIN_CALLBACK_DEF_H_
#define OXM_RANDOM_PIN_SIZE 8
/**
- * Function pointer to print pin code
+ * Function pointer to print pin code.
*/
typedef void (*GeneratePinCallback)(char* pinData, size_t pinSize);
/**
- * Function pointer to input pin code
+ * Function pointer to input pin code.
*/
typedef void (*InputPinCallback)(char* pinBuf, size_t bufSize);
/**
- * Function to setting generate PIN callback from user
+ * Function to setting generate PIN callback from user.
*
- * @param[in] pinCB implementation of generate PIN callback
+ * @param pinCB implementation of generate PIN callback.
*/
void SetGeneratePinCB(GeneratePinCallback pinCB);
/**
- * Function to setting input PIN callback from user
+ * Function to setting input PIN callback from user.
*
- * @param[in] pinCB implementation of input PIN callback
+ * @param pinCB implementation of input PIN callback.
*/
void SetInputPinCB(InputPinCallback pinCB);
* Function to generate random PIN.
* This function will send generated PIN to user via callback.
*
- * @param[in,out] pinBuffer Buffer to store the generated PIN data.
- * @param[in] bufferSize Size of buffer
- * @return OC_STACK_SUCCESS in case of success and other value otherwise.
+ * @param pinBuffer is the reference to the buffer to store the generated PIN data.
+ * @param bufferSize is the size of buffer.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success or other value in case of error.
*/
OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize);
/**
- * Function to input PIN callback via input callback
+ * Function to input PIN callback via input callback.
+ *
+ * @param[in,out] pinBuffer is the reference to the buffer to store the inputed PIN data.
+ * @param[in] bufferSize is the size of buffer.
*
- * @param[in,out] pinBuffer Buffer to store the inputed PIN data.
- * @param[in] bufferSize Size of buffer
- * @return OC_STACK_SUCCESS in case of success and other value otherwise.
+ * @return ::OC_STACK_SUCCESS in case of success or other value in ccase of error.
*/
OCStackResult InputPin(char* pinBuffer, size_t bufferSize);
#endif
/**
- * @brief Values used to create bit-maskable enums for single-value
- * response with embedded code.
+ * Values used to create bit-maskable enums for single-value response with
+ * embedded code.
*/
#define ACCESS_GRANTED_DEF (1 << 0)
#define ACCESS_DENIED_DEF (1 << 1)
} OSCTBitmask_t;
/**
- * @brief /oic/sec/credtype (Credential Type) data type.
- * Derived from OIC Security Spec /oic/sec/cred; see Spec for details.
+ * /oic/sec/credtype (Credential Type) data type.
+ * Derived from OIC Security Spec /oic/sec/cred; see Spec for details.
* 0: no security mode
* 1: symmetric pair-wise key
* 2: symmetric group key
typedef enum
{
+ OIC_R_ACL_TYPE = 0,
+ OIC_R_AMACL_TYPE,
+ OIC_R_CRED_TYPE,
+ OIC_R_CRL_TYPE,
+ OIC_R_DOXM_TYPE,
+ OIC_R_DPAIRING_TYPE,
+ OIC_R_PCONF_TYPE,
+ OIC_R_PSTAT_TYPE,
+ OIC_R_SACL_TYPE,
+ OIC_R_SVC_TYPE,
+ OIC_SEC_SVR_TYPE_COUNT, //define the value to number of SVR
+ NOT_A_SVR_RESOURCE = 99
+}OicSecSvrType_t;
+
+typedef enum
+{
OIC_JUST_WORKS = 0x0,
OIC_RANDOM_DEVICE_PIN = 0x1,
OIC_MANUFACTURER_CERTIFICATE = 0x2,
OIC_OXM_COUNT
}OicSecOxm_t;
-typedef struct OicSecJwk OicSecJwk_t;
+typedef struct OicSecKey OicSecKey_t;
typedef struct OicSecPstat OicSecPstat_t;
#ifdef __WITH_X509__
typedef struct OicSecCrl OicSecCrl_t;
+typedef ByteArray OicSecCert_t;
+#else
+typedef void OicSecCert_t;
#endif /* __WITH_X509__ */
/**
- * @brief /oic/uuid (Universal Unique Identifier) data type.
+ * /oic/uuid (Universal Unique Identifier) data type.
*/
#define UUID_LENGTH 128/8 // 128-bit GUID length
//TODO: Confirm the length and type of ROLEID.
};
/**
- * @brief /oic/sec/jwk (JSON Web Key) data type.
- * See JSON Web Key (JWK) draft-ietf-jose-json-web-key-41
+ * /oic/sec/jwk (JSON Web Key) data type.
+ * See JSON Web Key (JWK) draft-ietf-jose-json-web-key-41
*/
#define JWK_LENGTH 256/8 // 256 bit key length
-struct OicSecJwk
+struct OicSecKey
{
- char *data;
+ uint8_t *data;
+ size_t len;
};
/**
- * @brief /oic/sec/acl (Access Control List) data type.
- * Derived from OIC Security Spec; see Spec for details.
+ * /oic/sec/acl (Access Control List) data type.
+ * Derived from OIC Security Spec; see Spec for details.
*/
struct OicSecAcl
{
size_t prdRecrLen; // the number of elts in Periods
char **periods; // 3:R:M*:N:String (<--M*; see Spec)
char **recurrences; // 5:R:M:N:String
- size_t ownersLen; // the number of elts in Owners
- OicUuid_t *owners; // 8:R:M:Y:oic.uuid
- // NOTE: we are using UUID for Owners instead of Svc type for mid-April
- // SRM version only; this will change to Svc type for full implementation.
- //TODO change Owners type to oic.sec.svc
- //OicSecSvc_t *Owners; // 6:R:M:Y:oic.sec.svc
+ OicUuid_t rownerID; // 8:R:S:Y:oic.uuid
OicSecAcl_t *next;
};
/**
- * @brief /oic/sec/amacl (Access Manager Service Accesss Control List)
- * data type.
- * Derived from OIC Security Spec; see Spec for details.
+ * /oic/sec/amacl (Access Manager Service Accesss Control List) data type.
+ * Derived from OIC Security Spec; see Spec for details.
*/
struct OicSecAmacl
{
char **resources; // 0:R:M:Y:String
size_t amssLen; // the number of elts in Amss
OicUuid_t *amss; // 1:R:M:Y:acl
- size_t ownersLen; // the number of elts in Owners
- OicUuid_t *owners; // 2:R:M:Y:oic.uuid
- // NOTE: we are using UUID for Owners instead of Svc type for mid-April
- // SRM version only; this will change to Svc type for full implementation.
- //TODO change Owners type to oic.sec.svc
- //OicSecSvc_t *Owners; // 2:R:M:Y:oic.sec.svc
+ OicUuid_t rownerID; // 2:R:S:Y:oic.uuid
OicSecAmacl_t *next;
};
/**
- * @brief /oic/sec/cred (Credential) data type.
- * Derived from OIC Security Spec; see Spec for details.
+ * /oic/sec/cred (Credential) data type.
+ * Derived from OIC Security Spec; see Spec for details.
*/
struct OicSecCred
{
//size_t roleIdsLen; // the number of elts in RoleIds
//OicSecRole_t *roleIds; // 2:R:M:N:oic.sec.role
OicSecCredType_t credType; // 3:R:S:Y:oic.sec.credtype
- OicSecJwk_t publicData; // 5:R:S:N:oic.sec.jwk
- OicSecJwk_t privateData; // 6:R:S:N:oic.sec.jwk
+#ifdef __WITH_X509__
+ OicSecCert_t publicData; // chain of certificates
+#endif /* __WITH_X509__ */
+ OicSecKey_t privateData; // 6:R:S:N:oic.sec.key
char *period; // 7:R:S:N:String
- size_t ownersLen; // the number of elts in Owners
- OicUuid_t *owners; // 8:R:M:Y:oic.uuid
- // NOTE: we are using UUID for Owners instead of Svc type for mid-April
- // SRM version only; this will change to Svc type for full implementation.
- //OicSecSvc_t *Owners; // 8:R:M:Y:oic.sec.svc
- //TODO change Owners type to oic.sec.svc
+ OicUuid_t rownerID; // 8:R:S:Y:oic.uuid
OicSecCred_t *next;
};
/**
- * @brief /oic/sec/doxm (Device Owner Transfer Methods) data type
- * Derived from OIC Security Spec; see Spec for details.
+ * /oic/sec/doxm (Device Owner Transfer Methods) data type
+ * Derived from OIC Security Spec; see Spec for details.
*/
struct OicSecDoxm
{
//TODO: Need more clarification on deviceIDFormat field type.
//OicSecDvcIdFrmt_t deviceIDFormat; // 5:R:S:Y:UINT8
OicUuid_t deviceID; // 6:R:S:Y:oic.uuid
- bool dpc; // 7:R:S:Y:Boolean
- OicUuid_t owner; // 7:R:S:Y:oic.uuid
- // NOTE: we are using UUID for Owner instead of Svc type for mid-April
- // SRM version only; this will change to Svc type for full implementation.
- //OicSecSvc_t devOwner; // 7:R:S:Y:oic.sec.svc
- //OicSecSvc_t rOwner; // 8:R:S:Y:oic.sec.svc
- //TODO change Owner type to oic.sec.svc
+ bool dpc; // 7:R:S:Y:Boolean
+ OicUuid_t owner; // 8:R:S:Y:oic.uuid
+ OicUuid_t rownerID; // 9:R:S:Y:oic.uuid
};
/**
- * @brief /oic/sec/pstat (Provisioning Status) data type.
+ * /oic/sec/pstat (Provisioning Status) data type.
* NOTE: this struct is ahead of Spec v0.95 in definition to include Sm.
* TODO: change comment when reconciled to Spec v0.96.
*/
size_t smLen; // the number of elts in Sm
OicSecDpom_t *sm; // 5:R:M:Y:oic.sec.dpom
uint16_t commitHash; // 6:R:S:Y:oic.sec.sha256
- //TODO: this is supposed to be a 256-bit uint; temporarily use uint16_t
- //TODO: need to decide which 256 bit and 128 bit types to use... boost?
+ OicUuid_t rownerID; // 7:R:S:Y:oic.uuid
};
/**
- * @brief /oic/sec/role (Role) data type.
- * Derived from OIC Security Spec; see Spec for details.
+ * /oic/sec/role (Role) data type.
+ * Derived from OIC Security Spec; see Spec for details.
*/
struct OicSecRole
{
};
/**
- * @brief /oic/sec/sacl (Signed Access Control List) data type.
- * Derived from OIC Security Spec; see Spec for details.
+ * /oic/sec/sacl (Signed Access Control List) data type.
+ * Derived from OIC Security Spec; see Spec for details.
*/
struct OicSecSacl
{
};
/**
- * @brief /oic/sec/svc (Service requiring a secure connection) data type.
- * Derived from OIC Security Spec; see Spec for details.
+ * /oic/sec/svc (Service requiring a secure connection) data type.
+ * Derived from OIC Security Spec; see Spec for details.
*/
struct OicSecSvc
{
struct OicPin
{
- uint8_t val[DP_PIN_LENGTH+1];
+ uint8_t val[DP_PIN_LENGTH];
};
/**
OicUuid_t *pddevs; // 4:R:M:Y:oic.uuid
size_t pddevLen; // the number of elts in pddev
OicUuid_t deviceID; // 5:R:S:Y:oic.uuid
- OicUuid_t rowner; // 6:R:S:Y:oic.uuid
+ OicUuid_t rownerID; // 6:R:S:Y:oic.uuid
};
/**
// <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
OicSecPrm_t spm; // 0:R/W:S:Y:UINT16
OicUuid_t pdeviceID; // 1:R:S:Y:oic.uuid
- OicUuid_t rowner; // 2:R:S:Y:oic.uuid
+ OicUuid_t rownerID; // 2:R:S:Y:oic.uuid
+};
+
+#define MAX_VERSION_LEN 16 // Security Version length. i.e., 00.00.000 + reserved space
+
+/**
+ * @brief security version data type
+ */
+typedef struct OicSecVer OicSecVer_t;
+
+/**
+ * @brief /oic/sec/ver (Security Version) data type
+ */
+struct OicSecVer
+{
+ // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+ char secv[MAX_VERSION_LEN]; // 0:R:S:Y:String
+ OicUuid_t deviceID; // 1:R:S:Y:oic.uuid
};
#ifdef __cplusplus
}
#endif
-
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
-
typedef struct OicParseQueryIter OicParseQueryIter_t;
/**
- * @brief OicRestQueryIter data structure is used for book-keeping
- * sub-REST query's attribute's and value's, starting location &
- * length between calls to GetNextQuery(). This struct needs
- * to be first initialized with ParseQueryIterInit().
+ * OicRestQueryIter data structure is used for book-keeping
+ * sub-REST query's attribute's and value's, starting location &
+ * length between calls to GetNextQuery(). This struct needs
+ * to be first initialized with ParseQueryIterInit().
*
*/
struct OicParseQueryIter
{
- unsigned char * attrPos; /**<stating location of attribute */
- size_t attrLen; /**<length of the attribute */
- unsigned char * valPos; /**<starting location of value*/
- size_t valLen; /**<length of the value*/
- coap_parse_iterator_t pi; /**<coap struct for tokenizing the query*/
+ unsigned char * attrPos; /**< stating location of attribute. */
+ size_t attrLen; /**< length of the attribute. */
+ unsigned char * valPos; /**< starting location of value. */
+ size_t valLen; /**< length of the value. */
+ coap_parse_iterator_t pi; /**< coap struct for tokenizing the query.*/
};
/**
- * @def VERIFY_SUCCESS
- * @brief Macro to verify success of operation.
+ * Macro to verify success of operation.
* eg: VERIFY_SUCCESS(TAG, OC_STACK_OK == foo(), ERROR);
* @note Invoking function must define "exit:" label for goto functionality to work correctly.
- *
*/
#define VERIFY_SUCCESS(tag, op, logLevel) do{ if (!(op)) \
{OIC_LOG((logLevel), tag, #op " failed!!"); goto exit; } }while(0)
/**
- * @def VERIFY_NON_NULL
- * @brief Macro to verify argument is not equal to NULL.
+ * Macro to verify argument is not equal to NULL.
* eg: VERIFY_NON_NULL(TAG, ptrData, ERROR);
* @note Invoking function must define "exit:" label for goto functionality to work correctly.
- *
*/
#define VERIFY_NON_NULL(tag, arg, logLevel) do{ if (NULL == (arg)) \
{ OIC_LOG((logLevel), tag, #arg " is NULL"); goto exit; } }while(0)
/**
- * This method initializes the OicParseQueryIter_t struct
- *
- *@param query - REST query, to be parsed
- *@param parseIter - OicParseQueryIter_t struct, to be initialized
+ * This method initializes the @ref OicParseQueryIter_t struct.
*
+ * @param query is the REST query, to be parsed.
+ * @param parseIter is the @ref OicParseQueryIter_t struct, to be initialized based on the query.
*/
-void ParseQueryIterInit(unsigned char * query, OicParseQueryIter_t * parseIter);
-
+void ParseQueryIterInit(const unsigned char * query, OicParseQueryIter_t * parseIter);
/**
- * This method fills the OicParseQueryIter_t struct with next REST query's
- * attribute's and value's information
+ * This method fills the @ref OicParseQueryIter_t struct with next REST query's
+ * attribute's and value's information.
*
- *@param parseIter - OicParseQueryIter_t struct, has next query's attribute's & value's info
+ * @param parseIter is the @ref OicParseQueryIter_t struct, has next query's attribute's
+ * & value's info.
*
- * @retval
- * OicParseQueryIter_t * - has parsed query info
- * NULL - has no query to parse
+ * @return reference to the @ref OicParseQueryIter_t if it has parsed query info, else
+ * NULL if it has no query to parse.
*/
OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter);
-
-
/**
- * This method acts as a helper funtion for JSON unmarshalling by various SVR's.
+ * This method acts as a helper function for JSON unmarshalling by various SVR's.
*
- * @param jsonRoot - root JSON node containing the OicUuid array
- * @param arrayItem - name of the JSON OicUuid array item
- * @param numUuids - pointer to the number of OicUuid's available in JSON array
- * @param uuids - pointer to the array of OicUuid's
+ * @param jsonRoot point to the root JSON node containing the OicUuid array.
+ * @param arrayItem is the name of the JSON OicUuid array item.
+ * @param numUuids is the pointer to the number of OicUuid's available in JSON array.
+ * @param uuids is the pointer to the array of OicUuid's.
*
* @return ::OC_STACK_OK on success, some other value upon failure.
*/
-OCStackResult AddUuidArray(cJSON* jsonRoot, const char* arrayItem,
- size_t *numUuids, OicUuid_t** uuids );
+OCStackResult AddUuidArray(const cJSON* jsonRoot, const char* arrayItem,
+ size_t *numUuids, OicUuid_t** uuids);
/**
* Function to getting string of ownership transfer method
*/
const char* GetOxmString(OicSecOxm_t oxmType);
+/*
+ * This method converts UUID to canonical format string.
+ *
+ * @param uuid Device UUID
+ * @param strUuid converted UUID in canonical format
+ * @return OC_STACK_OK for success.
+ *
+ * @note Caller needs to invoke OICFree after done using the return pointer
+ */
+OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid);
+
+
+/*
+ * This method converts string UUID to OicUuid_t.
+ *
+ * @param strUuid Device UUID in string format
+ * @param uuid converted UUID in OicUuid_t format
+ * @return OC_STACK_OK for success.
+ *
+ */
+OCStackResult ConvertStrToUuid(const char* strUuid, OicUuid_t* uuid);
+
+
#ifdef __cplusplus
}
#endif // __cplusplus
provisioning_env.AppendUnique(LIBS = ['gnustl_static'])
if not env.get('RELEASE'):
- provisioning_env.AppendUnique(LIBS = ['log'])
+ provisioning_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
if target_os in ['darwin', 'ios']:
provisioning_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE'])
* @param[in] certFileName pointer to null-terminated string with file name
* @return PKI_SUCCESS if success, error code otherwise
*/
-PKIError GenerateDERCertificateFile (const ByteArray *certificate, const char *certFileName);
+PKIError GenerateDERCertificateFile (const ByteArray *certificate, const char * const certFileName);
/**
* Issues certificate signing request with specified parameters.
#define DEFAULT_CONTEXT_VALUE 0x99
#define STATE "state"
#define OPEN_DURATION "openDuration"
+#define OPEN_DURATION_TIME "10min"
#define OPEN_ALARM "openAlarm"
static const char MULTICAST_DISCOVERY_QUERY[] = "/oic/res";
static int coapSecureResource;
-static const char CRED_FILE[] = "oic_svr_db_door.json";
+static const char CRED_FILE[] = "oic_svr_db_door.dat";
CAEndpoint_t endpoint = {CA_DEFAULT_ADAPTER, CA_DEFAULT_FLAGS, 0, {0}, 0};
}
doorResource->state = STATE_CLOSED; //1:closed , 0: open
- char str[] = "10min";
- doorResource->openDuration = str;
+ doorResource->openDuration = OPEN_DURATION_TIME;
doorResource->openAlarm = false;
OCStackResult res = OCCreateResource(&(doorResource->handle),
"core.door",
OCStackResult ret;
OIC_LOG(INFO, TAG, "Send Get REQ to Light server");
+ //select ciphersuite for certificates
+ CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
+
initAddress();
char szQueryUri[64] = { '\0'};
//Secure Virtual Resource database for Iotivity Server
//It contains Server's Identity and the PSK credentials
//of other devices which the server trusts
-static char CRED_FILE[] = "oic_svr_db_light.json";
+static char CRED_FILE[] = "oic_svr_db_light.dat";
//Structure to represent a light resource and its attributes
provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
sec_provisioning_src_dir + 'oic_svr_db_door.json'))
provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
+ sec_provisioning_src_dir + 'oic_svr_db_pt.dat'))
+provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
+ sec_provisioning_src_dir + 'oic_svr_db_light.dat'))
+provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
+ sec_provisioning_src_dir + 'oic_svr_db_door.dat'))
+provisioning_env.Alias("install", provisioning_env.Install( sec_provisioning_build_dir,
sec_provisioning_src_dir + 'README.txt'))
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/res/d",
- "/oic/res/types/d",
- "/oic/presence"
- ],
- "perms": 2,
- "ownrs" : [
- "ZG9vckRldmljZVVVSUQwMA=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl",
- "/oic/sec/crl",
- "/oic/sec/cred"
- ],
- "perms": 6,
- "ownrs" : [
- "ZG9vckRldmljZVVVSUQwMA=="
- ]
- }
- ],
- "pstat": {
- "isop": false,
- "deviceid": "ZG9vckRldmljZVVVSUQwMA==",
- "commithash": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": false,
- "deviceid": "ZG9vckRldmljZVVVSUQwMA=="
- }
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/presence",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/crl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/cred",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "646F6F72-4465-7669-6365-555549443030"\r
+ },\r
+ "pstat": {\r
+ "isop": false,\r
+ "deviceuuid": "646F6F72-4465-7669-6365-555549443030",\r
+ "rowneruuid": "646F6F72-4465-7669-6365-555549443030",\r
+ "cm": 2,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": false,\r
+ "deviceuuid": "646F6F72-4465-7669-6365-555549443030",\r
+ "rowneruuid": "646F6F72-4465-7669-6365-555549443030",\r
+ "dpc": false\r
+ }\r
}
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/res/d",
- "/oic/res/types/d",
- "/oic/presence"
- ],
- "perms": 2,
- "ownrs" : [
- "bGlnaHREZXZpY2VVVUlEMA=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl",
- "/oic/sec/crl",
- "/oic/sec/cred"
- ],
- "perms": 6,
- "ownrs" : [
- "bGlnaHREZXZpY2VVVUlEMA=="
- ]
- }
- ],
- "pstat": {
- "isop": false,
- "deviceid": "bGlnaHREZXZpY2VVVUlEMA==",
- "commithash": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": false,
- "deviceid": "bGlnaHREZXZpY2VVVUlEMA=="
- }
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/presence",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/crl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/cred",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "6C696768-7444-6576-6963-655555494430"\r
+ },\r
+ "pstat": {\r
+ "isop": false,\r
+ "deviceuuid": "6C696768-7444-6576-6963-655555494430",\r
+ "rowneruuid": "6C696768-7444-6576-6963-655555494430",\r
+ "cm": 2,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": false,\r
+ "deviceuuid": "6C696768-7444-6576-6963-655555494430",\r
+ "rowneruuid": "6C696768-7444-6576-6963-655555494430",\r
+ "dpc": false\r
+ }\r
}
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlEMA=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl",
- "/oic/sec/cred"
- ],
- "perms": 7,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlEMA=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlEMA==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlEMA==",
- "ownr": "YWRtaW5EZXZpY2VVVUlEMA=="
- }
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "61646D69-6E44-6576-6963-655555494430"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "rowneruuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "cm": 2,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "devowneruuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "rowneruuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "dpc": false\r
+ }\r
+}
\ No newline at end of file
static OicSecAcl_t *gAcl = NULL;
static OicSecCrl_t *gCrl = NULL;
-static char PROV_TOOL_DB_FILE[] = "oic_svr_db_pt.json";
+static char PROV_TOOL_DB_FILE[] = "oic_svr_db_pt.dat";
static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
static int gOwnershipState = 0;
}
OICFree((acl)->resources);
- /* Clean Owners */
- OICFree((acl)->owners);
-
/* Clean ACL node itself */
OICFree((acl));
}
while (0 != CalculateAclPermission(temp_pms, &(acl->permission)) );
// Set Rowner
- printf("Num. of Rowner : ");
- ret = scanf("%zu", &acl->ownersLen);
- if(-1 == ret)
- {
- printf("Error while input\n");
- return -1;
- }
printf("-URN identifying the rowner\n");
printf("ex) lightDeviceUUID0 (16 Numbers except to '-')\n");
- acl->owners = (OicUuid_t *)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
- if (NULL == acl->owners)
+
+ printf("Rowner : ");
+ char *ptr_temp_id = NULL;
+ ret = scanf("%19ms", &ptr_temp_id);
+ if (1 == ret)
{
- OIC_LOG(ERROR, TAG, "Error while memory allocation");
+ OICStrcpy(temp_id, sizeof(temp_id), ptr_temp_id);
+ OICFree(ptr_temp_id);
+ }
+ else
+ {
+ printf("Error while input\n");
return -1;
}
- for (size_t i = 0; i < acl->ownersLen; i++)
+ j = 0;
+ for (int k = 0; temp_id[k] != '\0'; k++)
{
- printf("[%zu]Rowner : ", i + 1);
- char *ptr_temp_id = NULL;
- ret = scanf("%19ms", &ptr_temp_id);
- if (1 == ret)
- {
- OICStrcpy(temp_id, sizeof(temp_id), ptr_temp_id);
- OICFree(ptr_temp_id);
- }
- else
- {
- printf("Error while input\n");
- return -1;
- }
- j = 0;
- for (int k = 0; temp_id[k] != '\0'; k++)
+ if (DASH != temp_id[k])
{
- if (DASH != temp_id[k])
- {
- acl->owners[i].id[j++] = temp_id[k];
- }
+ acl->rownerID.id[j++] = temp_id[k];
}
}
return 0;
#include "crlresource.h"
#include "oic_malloc.h"
+#ifdef __unix__
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif // __unix__
+
/* The first octet of the OCTET STRING indicates whether the key is
compressed or uncompressed. The uncompressed form is indicated by 0x04
and the compressed form is indicated by either 0x02 or 0x03 (RFC 5480)*/
);
}
-PKIError GenerateDERCertificateFile (const ByteArray *certificate, const char *certFileName)
+PKIError GenerateDERCertificateFile (const ByteArray *certificate, const char * const certFileName)
{
FUNCTION_INIT();
+
+#ifdef __unix__
+ struct stat st;
+ int fd = -1;
+#else
FILE *filePointer = NULL;
+#endif
CHECK_NULL(certFileName, ISSUER_NULL_PASSED);
CHECK_NULL(certificate, ISSUER_NULL_PASSED);
CHECK_NULL(certificate->data, ISSUER_NULL_PASSED);
+
+#ifdef __unix__
+ fd = open(certFileName, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
+ CHECK_NOT_EQUAL(fd, -1, ISSUER_NULL_PASSED);
+ CHECK_EQUAL(fstat(fd, &st), 0, ISSUER_NULL_PASSED);
+ CHECK_COND(S_ISREG(st.st_mode), ISSUER_FILE_WRITE_ERROR);
+ CHECK_COND(!S_ISLNK(st.st_mode), ISSUER_FILE_WRITE_ERROR);
+ CHECK_EQUAL(write(fd, certificate->data, certificate->len), (ssize_t) certificate->len,
+ ISSUER_FILE_WRITE_ERROR);
+
+ FUNCTION_CLEAR(
+ if(-1 != fd)
+ {
+ close(fd);
+ }
+ );
+#else
filePointer = fopen(certFileName, "wb");
CHECK_NULL(filePointer, ISSUER_FILE_WRITE_ERROR);
CHECK_EQUAL(fwrite(certificate->data, 1, certificate->len, filePointer), certificate->len,
FUNCTION_CLEAR(
if(filePointer)
- {
- fclose(filePointer);
- }
+ {
+ fclose(filePointer);
+ }
filePointer = NULL;
);
+#endif
+
}
PKIError SetSerialNumber (const long serNum)
#include "crlresource.h"
#include "crl_generator.h"
+#ifdef __unix__
+#include <sys/stat.h>
+#endif // __unix__
+
//constants used in ckmInfo
#define CKM_INFO_IS_NOT_LOADED (0)
#define CKM_INFO_IS_LOADED (1)
}
else ////create new storage
{
+#ifdef __unix__
+ struct stat st;
+ if (0 == lstat(CA_STORAGE_FILE, &st))
+ {
+ CHECK_COND(S_ISREG(st.st_mode), ISSUER_FILE_WRITE_ERROR);
+ CHECK_COND(!S_ISLNK(st.st_mode), ISSUER_FILE_WRITE_ERROR);
+ }
+#endif
filePointer = fopen(CA_STORAGE_FILE, "wb");
CHECK_NULL(filePointer, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
objectsWrote = fwrite(&g_ckmInfo, sizeof(CKMInfo_t), count, filePointer);
FILE *filePointer = NULL;
int count = 1;
int objectsWrote = 0;
+#ifdef __unix__
+ struct stat st;
+#endif
CHECK_COND(g_ckmInfo.CKMInfoIsLoaded, CKM_INFO_IS_NOT_INIT);
+#ifdef __unix__
+ if (0 == lstat(CA_STORAGE_FILE, &st))
+ {
+ CHECK_COND(S_ISREG(st.st_mode), ISSUER_FILE_WRITE_ERROR);
+ CHECK_COND(!S_ISLNK(st.st_mode), ISSUER_FILE_WRITE_ERROR);
+ }
+#endif
filePointer = fopen(CA_STORAGE_FILE, "wb");
CHECK_NULL(filePointer, ISSUER_CA_STORAGE_FILE_WRITE_ERROR);
objectsWrote = fwrite(&g_ckmInfo, sizeof(CKMInfo_t), count, filePointer);
FILE *filePointer = NULL;
uint32_t objectsWrote = 0;
uint8_t prefix[CERT_LEN_PREFIX] = {0};
-
+#ifdef __unix__
+ struct stat st;
+ if (0 == lstat(CA_STORAGE_CRT_FILE, &st))
+ {
+ CHECK_COND(S_ISREG(st.st_mode), ISSUER_FILE_WRITE_ERROR);
+ CHECK_COND(!S_ISLNK(st.st_mode), ISSUER_FILE_WRITE_ERROR);
+ }
+#endif
filePointer = fopen(CA_STORAGE_CRT_FILE, "wb");
CHECK_NULL(filePointer, ISSUER_CA_STORAGE_CRT_WRITE_ERROR);
CHECK_COND(g_crlInfo.CrlData.data, ISSUER_CA_STORAGE_CRL_UNDEFINED);
CHECK_NULL_BYTE_ARRAY_PTR(certificateRevocationList, ISSUER_CA_STORAGE_NULL_PASSED);
tmpCRL = (OicSecCrl_t *)GetCRLResource();
+ CHECK_NULL(tmpCRL, ISSUER_CA_STORAGE_NULL_PASSED);
g_crlInfo.CrlId = tmpCRL->CrlId;
g_crlInfo.CrlData = tmpCRL->CrlData;
g_crlInfo.ThisUpdate = tmpCRL->ThisUpdate;
unittest_src_dir + 'capub.der',
unittest_src_dir + 'cert_chain.dat',
unittest_src_dir + 'chain.der',
- unittest_src_dir + 'CKMInfo.json' ]))
+ unittest_src_dir + 'CKMInfo.dat' ]))
env.AppendTarget('test')
if env.get('TEST') == '1':
#define READ_WRITE_BLOCK_N 1ul
#define N_LENGTH_BYTES 3
-const char *CKMI_JSON_FILE_NAME = "CKMInfo.json";
+const char *CKMI_PS_FILE_NAME = "CKMInfo.dat";
#define CRL_DEFAULT_CRL_ID 1
#define CRL_DEFAULT_THIS_UPDATE "150101000000Z"
FILE* ckm_fopen(const char * /*path*/, const char *mode)
{
- return fopen(CKMI_JSON_FILE_NAME, mode);
+ return fopen(CKMI_PS_FILE_NAME, mode);
}
void SetPersistentHandler(OCPersistentStorage *ps)
defaultCrl->ThisUpdate.len = strlen(CRL_DEFAULT_THIS_UPDATE);
EXPECT_EQ(OC_STACK_OK, UpdateCRLResource(defaultCrl));
- EXPECT_NE((void *)NULL, GetBase64CRL());
+ EXPECT_NE((void *)NULL, GetCrl());
OICFree(defaultCrl);
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlE"]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl",
- "/oic/sec/cred"
- ],
- "perms": 7,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlE"]
- }
- ],
- "crl": {
- "CRLId": 1,
- "ThisUpdate": "MTUwMTAxMDAwMDAwWg==",
- "CRLData": "LQ=="
- },
- "pstat": {
- "isop": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlE",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "owned": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlE",
- "ownr": "YWRtaW5EZXZpY2VVVUlE"
- }
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/cred",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 7\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "61646d69-6e44-6576-6963-655555494430"\r
+ },\r
+ "crl": {\r
+ "CRLId": 1,\r
+ "ThisUpdate": "150101000000Z",\r
+ "CRLData": "-"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "61646d69-6e44-6576-6963-655555494430",\r
+ "rowneruuid": "61646d69-6e44-6576-6963-655555494430",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "61646d69-6e44-6576-6963-655555494430",\r
+ "devowneruuid": "61646d69-6e44-6576-6963-655555494430",\r
+ "rowneruuid": "61646d69-6e44-6576-6963-655555494430",\r
+ "dpc": false\r
+ }\r
+}
\ No newline at end of file
/*\r
* Callback for creating CoAP payload.\r
*/\r
-typedef char* (*OTMCreatePayloadCallback)(OTMContext_t* otmCtx);\r
+typedef OCStackResult (*OTMCreatePayloadCallback)(OTMContext_t* otmCtx, uint8_t **payload,\r
+ size_t *size);\r
\r
/**\r
* Required callback for performing ownership transfer\r
*/\r
-typedef struct OTMCallbackData{\r
+typedef struct OTMCallbackData\r
+{\r
OTMLoadSecret loadSecretCB;\r
OTMCreateSecureSession createSecureSessionCB;\r
OTMCreatePayloadCallback createSelectOxmPayloadCB;\r
OTMCreatePayloadCallback createOwnerTransferPayloadCB;\r
-}OTMCallbackData_t;\r
+} OTMCallbackData_t;\r
\r
/**\r
* Set the callbacks for ownership transfer\r
*/
OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
OicSecAcl_t *acl, OCProvisionResultCB resultCallback);
+
+#ifdef __WITH_X509__
+/**
+ * API to send CRL information to resource.
+ *
+ * @param[in] selectedDeviceInfo Selected target device.
+ * @param[in] crl CRL to provision.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ * provisioning request recieves a response from resource server.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult SRPProvisionCRL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+ OicSecCrl_t *crl, OCProvisionResultCB resultCallback);
+#endif // __WITH_X509__
+/**
+ * API to send Direct-Pairing Configuration to a device.
+ *
+ * @param[in] selectedDeviceInfo Selected target device.
+ * @param[in] pconf PCONF pointer.
+ * @param[in] resultCallback callback provided by API user, callback will be called when
+ * provisioning request recieves a response from resource server.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
+ OicSecPconf_t *pconf, OCProvisionResultCB resultCallback);
/**
* API to send Direct-Pairing Configuration to a device.
* OCMode.\r
*\r
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from\r
- * client before returning the list of devices.\r
+ * server before returning the list of devices.\r
* @param[out] ppList List of candidate devices to be provisioned\r
* @return OTM_SUCCESS in case of success and other value otherwise.\r
*/\r
* all the device in subnet which are owned by calling provisioning client.\r
*\r
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from\r
- * client before returning the list of devices.\r
+ * server before returning the list of devices.\r
* @param[out] ppList List of device owned by provisioning tool.\r
* @return OTM_SUCCESS in case of success and other value otherwise.\r
*/\r
* variables pOwnedDevList and pUnownedDevList.\r
*\r
* @param[in] waitime Wait time for the API. The wait time will be divided by 2, and half of wait time\r
- * will be used for unowned discovery and remaining half for owned discovery.\r
+ * will be used for unowned discovery and remaining half for owned discovery. So the wait time should be
+ * equal to or more than 2.
* @param[out] pOwnedDevList list of owned devices.\r
* @param[out] pUnownedDevList list of unowned devices.\r
* @return OC_STACK_OK in case of success and other value otherwise.\r
-/* *****************************************************************
- *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * *****************************************************************/
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef OXM_JUST_WORKS_H_
#define OXM_JUST_WORKS_H_
/**
* In case of just works OxM, no need to implement.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
*/
OCStackResult LoadSecretJustWorksCallback(OTMContext_t* UNUSED_PARAM);
/**
* To establish a secure channel with anonymous cipher suite
*
- * @param[in] selectedDeviceInfo Selected device infomation
- * @return OC_STACK_SUCCESS in case of success and other value otherwise.
+ * @param otmCtx Context of OTM, It includes current device information.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
*/
OCStackResult CreateSecureSessionJustWorksCallback(OTMContext_t* otmCtx);
/**
* Generate payload for select OxM request.
*
- * @param[in] selectedDeviceInfo Selected device infomation
- * @return DOXM JSON payload including the selected OxM.
- * NOTE : Returned memory should be deallocated by caller.
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPayload is the DOXM CBOR payload including the selected OxM.
+ * @note Returned memory should be deallocated by caller.
+ * @param cborSize is the size of the cborPayload.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
*/
-char* CreateJustWorksSelectOxmPayload(OTMContext_t* otmCtx);
+OCStackResult CreateJustWorksSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+ size_t *cborSize);
/**
* Generate payload for owner transfer request.
*
- * @param[in] selectedDeviceInfo Selected device infomation
- * @return DOXM JSON payload including the owner information.
- * NOTE : Returned memory should be deallocated by caller.
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPayload is the DOXM CBOR payload including the owner information.
+ * @note Returned memory should be deallocated by caller.
+ * @param cborSize is the size of the cborPayload.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
*/
-char* CreateJustWorksOwnerTransferPayload(OTMContext_t* otmCtx);
-
+OCStackResult CreateJustWorksOwnerTransferPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+ size_t *cborSize);
#ifdef __cplusplus
}
#endif
-#endif //OXM_JUST_WORKS_H_
\ No newline at end of file
+#endif //OXM_JUST_WORKS_H_
-/* *****************************************************************
- *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * *****************************************************************/
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef OXM_RANDOM_PIN_H_
#define OXM_RANDOM_PIN_H_
/**
* Callback implementation to input the PIN code from user.
*
- * @otmCtx Context of OTM, It includes current device infomation.
- * @return OC_STACK_SUCCESS in case of success and other value otherwise.
+ * @param otmCtx Context of OTM, It includes current device information.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
*/
-OCStackResult InputPinCodeCallback(OTMContext_t* otmCtx);
+OCStackResult InputPinCodeCallback(OTMContext_t *otmCtx);
/**
- * Callback implemenration to establish a secure channel with PSK cipher suite
+ * Callback implemenration to establish a secure channel with PSK cipher suite.
+ *
+ * @param otmCtx Context of OTM, It includes current device information.
*
- * @param[in] selectedDeviceInfo Selected device infomation
- * @return OC_STACK_SUCCESS in case of success and other value otherwise.
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
*/
-OCStackResult CreateSecureSessionRandomPinCallbak(OTMContext_t* otmCtx);
+OCStackResult CreateSecureSessionRandomPinCallback(OTMContext_t *otmCtx);
/**
* Generate payload for select OxM request.
*
- * @param[in] selectedDeviceInfo Selected device infomation
- * @return DOXM JSON payload including the selected OxM.
- * NOTE : Returned memory should be deallocated by caller.
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPaylaod is the DOXM CBOR payload including the selected OxM.
+ * @note Returned memory should be deallocated by caller.
+ * @param cborSize is the size of the cborPayload.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
*/
-char* CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx);
+OCStackResult CreatePinBasedSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+ size_t *cborSize);
/**
* Generate payload for owner transfer request.
*
- * @param[in] selectedDeviceInfo Selected device infomation
- * @return DOXM JSON payload including the owner information.
- * NOTE : Returned memory should be deallocated by caller.
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPaylaod is the DOXM CBOR payload including the owner information.
+ * @note Returned memory should be deallocated by caller.
+ * @param cborSize is the size of the cborPayload.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
*/
-char* CreatePinBasedOwnerTransferPayload(OTMContext_t* otmCtx);
+OCStackResult CreatePinBasedOwnerTransferPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+ size_t *cborSize);
#ifdef __cplusplus
}
OicSecDoxm_t *doxm; /**< Pointer to target's doxm resource. **/
OCConnectivityType connType; /**< Connectivity type of endpoint */
uint16_t securePort; /**< secure port **/
+ char secVer[MAX_VERSION_LEN]; /**< security version **/
DeviceStatus devStatus; /**< status of device **/
struct OCProvisionDev *next; /**< Next pointer. **/
}OCProvisionDev_t;
-LAST UPDATED 7/16/2015
+LAST UPDATED 3/28/2016
To execute Provisioning Tool sample:
1) Build IoTivity with security enabled:
- $ cd <iotivity-base>
- $ scons resource SECURED=1
+ $ cd <iotivity-base>
+ $ scons resource SECURED=1
+
2) Verify Provisioning Tool functionality using secure sample apps:
- On Resource Server Device which needs to be 'provisioned':
- $ cd <iotivity-base>/out/<...>/release/resource/csdk/stack/samples/linux/secure
- $ export LD_LIBRARY_PATH=<iotivity-base>/out/<...>/release
- $ cp ../../../../security/provisioning/sample/oic_svr_db_unowned_server.json oic_svr_db_server.json
- $ ./ocserverbasicops
+ Run Resource Server Device which needs to be 'provisioned' in the directory:
+ $ ./sampleserver_justworks (Just Works)
+ or
+ $ ./sampleserver_randompin (Random Pin)
+
+ Run Provisioning Tool Device:
+ $ ./provisioningclient
+
+ Provisioning Tool will provide prompts for discovery, ownership transfer, and provisioning.
+
+ Enter 10 (Discover All Un/Owned Devices on Network)
+ and you should see the list of discovered owned and unowned devices.
+
+ Then enter 20 (Register/Own All Discovered Unowned Devices) to perform ownership transfer
+ between the Server device and the Provisioning Tool device.
+
+ If the random pin server is running, you must enter the PIN code that
+ appears on the server terminal to finish ownership transfer.
+
+ Enter 12 (Discover Only Owned Devices on Network) to confirm that
+ ownership transfer succeeded. If successful,
+ you should find the Server device on the Owned device list.
+
+ 3) Verify Ownership Transfer using sample apps:
+
+ If you would like to check whether ownership transfer successfully
+ created credentials, replace the server and client sample DAT files
+ with oic_svr_db_client.dat and oic_svr_db_server.dat files from the
+ ownership transfer as follows:
+ $ cp ./oic_svr_db_client.dat <iotivity-base>/out/<...>/release/resource/csdk/stack/samples/linux/secure/oic_svr_db.client.dat
+ $ cp ./oic_svr_db_server_<...>.dat <iotivity-base>/out/<...>/release/resource/csdk/stack/samples/linux/secure/oic_svr_db.server.dat
+ Then move to the sample app directory
+ and execute the server and client apps:
+ $ cd <iotivity-base>/out/release/resource/csdk/stack/samples/linux/secure/
+ $ export LD_LIBRARY_PATH=<iotivity-base>/out/<...>/release/
+ $ ./ocserverbasicops
+ $ ./occlientbasicops -u 0 -t 3
- On Provisioning Tool Device:
- $ cd <iotivity-base>/out/<...>/release/resource/csdk/security/provisioning/sample
- $ ./provisioningclient
+ If successful, the client and server should successfully send and receive payloads.
- Follow the prompts on Provisioning Tool device and provisioning should be completed
- successfully. You should see a message 'Provisioning Success~!!'.
+ All security functionality operate using CBOR data (DAT files).
+ JSON files are for reference only as they are human-readable.
+ JSON files are not used by security-related functions.
+
+ If you wish to test functionality with data file
+ different from the provided default DAT file, modify the JSON files
+ (oic_svr_db_server_justworks.json, oic_svr_db_server_randompin.json)
+ and then use the JSON-to-CBOR conversion tool
+ (<iotivity-base>/out/<...>/release/resource/csdk/security/tool/json2cbor)
+ to create a new DAT file.
sec_provisioning_src_dir = src_dir + '/resource/csdk/security/provisioning/sample/'
sec_provisioning_build_dir = env.get('BUILD_DIR') +'/resource/csdk/security/provisioning/sample/'
-clientjson = provisioning_env.Install(sec_provisioning_build_dir,
- sec_provisioning_src_dir + 'oic_svr_db_client.json')
-justworksjson = provisioning_env.Install(sec_provisioning_build_dir,
- sec_provisioning_src_dir + 'oic_svr_db_server_justworks.json')
-randompinjson = provisioning_env.Install(sec_provisioning_build_dir,
- sec_provisioning_src_dir+ 'oic_svr_db_server_randompin.json')
+clientdat = provisioning_env.Install(sec_provisioning_build_dir,
+ sec_provisioning_src_dir + 'oic_svr_db_client.dat')
+justworksdat = provisioning_env.Install(sec_provisioning_build_dir,
+ sec_provisioning_src_dir + 'oic_svr_db_server_justworks.dat')
+randompindat = provisioning_env.Install(sec_provisioning_build_dir,
+ sec_provisioning_src_dir+ 'oic_svr_db_server_randompin.dat')
+randompin_with_emptyuuid_dat = provisioning_env.Install(sec_provisioning_build_dir,
+ sec_provisioning_src_dir+ 'oic_svr_db_randompin_with_empty_deviceid.dat')
-Alias("samples", [provisioningclient, sampleserver_justworks, sampleserver_randompin, clientjson, justworksjson, randompinjson])
+Alias("samples", [provisioningclient, sampleserver_justworks, sampleserver_randompin, clientdat, justworksdat, randompindat, randompin_with_emptyuuid_dat])
provisioning_env.AppendTarget('samples')
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/amacl"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlEMA=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlEMA=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlEMA==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlEMA==",
- "ownr": "YWRtaW5EZXZpY2VVVUlEMA=="
- }
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/amacl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } \r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "61646D69-6E44-6576-6963-655575696430"\r
+ }, \r
+ "pstat": {\r
+ "isop": true,\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3,\r
+ "deviceuuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "rowneruuid": "61646D69-6E44-6576-6963-655575696430"\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "dpc": false,\r
+ "devowneruuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "rowneruuid": "61646D69-6E44-6576-6963-655575696430"\r
+ }\r
+}\r
+++ /dev/null
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlE"]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl",
- "/oic/sec/cred"
- ],
- "perms": 7,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlE"]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlE",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlE",
- "ownr": "YWRtaW5EZXZpY2VVVUlE"
- }
-}
--- /dev/null
+{
+ "acl": {
+ "aclist": {
+ "aces": [
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/res",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/p",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/res/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/res/types/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/presence",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 2
+ },
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/sec/doxm",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/pstat",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/acl",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/cred",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 6
+ },
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/sec/pconf",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/dpairing",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 6
+ },
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/sec/ver",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 2
+ }
+ ]
+ },
+ "rowneruuid" : ""
+ },
+ "pstat": {
+ "isop": false,
+ "deviceuuid": "",
+ "rowneruuid": "",
+ "cm": 2,
+ "tm": 0,
+ "om": 3,
+ "sm": 3
+ },
+ "doxm": {
+ "oxms": [0, 1],
+ "oxmsel": 0,
+ "sct": 1,
+ "owned": false,
+ "deviceuuid": "",
+ "devowneruuid": "",
+ "rowneruuid": "",
+ "dpc": true
+ }
+}
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/res/d",
- "/oic/res/types/d",
- "/oic/presence"
- ],
- "perms": 2,
- "ownrs" : [
- "anVzdHdvcmtzRGV2VVVJRA=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl",
- "/oic/sec/cred"
- ],
- "perms": 6,
- "ownrs" : [
- "anVzdHdvcmtzRGV2VVVJRA=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/pconf",
- "/oic/sec/dpairing"
- ],
- "perms": 6,
- "ownrs" : [
- "anVzdHdvcmtzRGV2VVVJRA=="
- ]
- }
- ],
- "pstat": {
- "isop": false,
- "deviceid": "anVzdHdvcmtzRGV2VVVJRA==",
- "commithash": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": false,
- "deviceid": "anVzdHdvcmtzRGV2VVVJRA==",
- "dpc": true
- }
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },{\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },{\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/presence",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/cred",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/pconf",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/dpairing",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/ver",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "6A757374-776F-726B-4465-765575696430"\r
+ },\r
+ "pstat": {\r
+ "isop": false,\r
+ "deviceuuid": "6A757374-776F-726B-4465-765575696430",\r
+ "rowneruuid": "6A757374-776F-726B-4465-765575696430",\r
+ "cm": 2,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": false,\r
+ "deviceuuid": "6A757374-776F-726B-4465-765575696430",\r
+ "devowneruuid": "",\r
+ "rowneruuid": "6A757374-776F-726B-4465-765575696430",\r
+ "dpc": true\r
+ }\r
+}
\ No newline at end of file
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/res/d",
- "/oic/res/types/d",
- "/oic/presence"
- ],
- "perms": 2,
- "ownrs" : [
- "cmFuZG9tUGluRGV2VVVJRA=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl",
- "/oic/sec/cred"
- ],
- "perms": 6,
- "ownrs" : [
- "cmFuZG9tUGluRGV2VVVJRA=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/pconf",
- "/oic/sec/dpairing"
- ],
- "perms": 6,
- "ownrs" : [
- "cmFuZG9tUGluRGV2VVVJRA=="
- ]
- }
- ],
- "pstat": {
- "isop": false,
- "deviceid": "cmFuZG9tUGluRGV2VVVJRA==",
- "commithash": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0,1],
- "oxmsel": 0,
- "sct": 1,
- "owned": false,
- "deviceid": "cmFuZG9tUGluRGV2VVVJRA==",
- "dpc": true
- }
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/presence",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/cred",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/pconf",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/dpairing",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/ver",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "72616E64-5069-6E44-6576-557569643030"\r
+ },\r
+ "pstat": {\r
+ "isop": false,\r
+ "deviceuuid": "72616E64-5069-6E44-6576-557569643030",\r
+ "rowneruuid": "72616E64-5069-6E44-6576-557569643030",\r
+ "cm": 2,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0, 1],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": false,\r
+ "deviceuuid": "72616E64-5069-6E44-6576-557569643030",\r
+ "devowneruuid": "",\r
+ "rowneruuid": "72616E64-5069-6E44-6576-557569643030",\r
+ "dpc": true\r
+ }\r
+}\r
+++ /dev/null
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl",
- "/oic/sec/svc",
- "/oic/sec/amacl"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 6,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- }
- ],
- "pstat": {
- "isop": false,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": false,
- "deviceid": "MTExMTExMTExMTExMTExMQ=="
- }
-}
#define TAG "provisioningclient"
static const char* ACL_PEMISN[5] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
-static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.json";
+static const char* SVR_DB_FILE_NAME = "oic_svr_db_client.dat";
// '_' for separaing from the same constant variable in |srmresourcestrings.c|
static const char* PRVN_DB_FILE_NAME = "oic_prvn_mng.db";
static const OicSecPrm_t SUPPORTED_PRMS[1] =
return -1;
}
otmcb.loadSecretCB = InputPinCodeCallback;
- otmcb.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
+ otmcb.createSecureSessionCB = CreateSecureSessionRandomPinCallback;
otmcb.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
otmcb.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
if(OC_STACK_OK != OCSetOwnerTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &otmcb))
}
printf(" Entered Wrong Number. Please Enter Again\n");
}
- acl->ownersLen = 1;
- acl->owners = (OicUuid_t*) OICCalloc(1, sizeof(OicUuid_t));
- if(!acl->owners)
- {
- OIC_LOG(ERROR, TAG, "createAcl: OICCalloc error return");
- goto CRACL_ERROR;
- }
dev = getDevInst((const OCProvisionDev_t*)g_own_list, own_num);
if(!dev || !dev->doxm)
OIC_LOG(ERROR, TAG, "createAcl: device instance empty");
goto CRACL_ERROR;
}
- memcpy(acl->owners, &dev->doxm->deviceID, UUID_LENGTH);
+ memcpy(&acl->rownerID, &dev->doxm->deviceID, sizeof(OicUuid_t));
printf("\n");
return acl;
//Secure Virtual Resource database for Iotivity Server
//It contains Server's Identity and the PSK credentials
//of other devices which the server trusts
-static char CRED_FILE[] = "oic_svr_db_server_justworks.json";
+static char CRED_FILE[] = "oic_svr_db_server_justworks.dat";
/* Function that creates a new LED resource by calling the
* OCCreateResource() method.
//Secure Virtual Resource database for Iotivity Server
//It contains Server's Identity and the PSK credentials
//of other devices which the server trusts
-static char CRED_FILE[] = "oic_svr_db_server_randompin.json";
+static char CRED_FILE[] = "oic_svr_db_server_randompin.dat";
/* Function that creates a new LED resource by calling the
* OCCreateResource() method.
* *****************************************************************/
#include <string.h>
#include "credentialgenerator.h"
+#include "base64.h"
#include "oic_malloc.h"
#include "oic_string.h"
-#include "logger.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
#include "credresource.h"
#include "ocrandom.h"
-#include "base64.h"
+#include "srmutility.h"
#include "stdbool.h"
#include "securevirtualresourcetypes.h"
#ifdef __WITH_X509__
#include "ck_manager.h"
+//Certificate-related functions
+#define CERT_LEN_PREFIX (3)
+#define BYTE_SIZE (8) //bits
#define CHAIN_LEN (2) //TODO: replace by external define or a runtime value
#endif //__WITH_X509__
#define TAG "SRPAPI-CG"
-/**
- * @def PM_VERIFY_SUCCESS
- * @brief Macro to verify success of operation.
- * eg: PM_VERIFY_SUCCESS(TAG, OC_STACK_OK == foo(), OC_STACK_ERROR, ERROR);
- * @note Invoking function must define "bail:" label for goto functionality to work correctly and
- * must define "OCStackResult res" for setting error code.
- * */
-#define PM_VERIFY_SUCCESS(tag, op, errCode, logLevel) { if (!(op)) \
- {OIC_LOG((logLevel), tag, #op " failed!!"); res = errCode; goto bail;} }
-/**
- * @def PM_VERIFY_NON_NULL
- * @brief Macro to verify argument is not equal to NULL.
- * eg: PM_VERIFY_NON_NULL(TAG, ptrData, ERROR);
- * @note Invoking function must define "bail:" label for goto functionality to work correctly.
- * */
-#define PM_VERIFY_NON_NULL(tag, arg, errCode, logLevel) { if (NULL == (arg)) \
- { OIC_LOG((logLevel), tag, #arg " is NULL"); res = errCode; goto bail;} }
-
OCStackResult PMGeneratePairWiseCredentials(OicSecCredType_t type, size_t keySize,
- const OicUuid_t *ptDeviceId,
- const OicUuid_t *firstDeviceId, const OicUuid_t *secondDeviceId,
- OicSecCred_t **firstCred, OicSecCred_t **secondCred)
+ const OicUuid_t *ptDeviceId, const OicUuid_t *firstDeviceId,
+ const OicUuid_t *secondDeviceId, OicSecCred_t **firstCred, OicSecCred_t **secondCred)
{
-
if (NULL == ptDeviceId || NULL == firstDeviceId || NULL != *firstCred || \
NULL == secondDeviceId || NULL != *secondCred)
{
return OC_STACK_INVALID_PARAM;
}
OCStackResult res = OC_STACK_ERROR;
- uint8_t* privData = NULL;
- char* base64Buff = NULL;
OicSecCred_t *tempFirstCred = NULL;
OicSecCred_t *tempSecondCred = NULL;
size_t privDataKeySize = keySize;
- privData = (uint8_t*) OICCalloc(privDataKeySize,sizeof(uint8_t));
- PM_VERIFY_NON_NULL(TAG, privData, OC_STACK_NO_MEMORY, ERROR);
-
- OCFillRandomMem(privData,privDataKeySize);
+ uint8_t *privData = (uint8_t *)OICCalloc(privDataKeySize, sizeof(uint8_t));
+ VERIFY_NON_NULL(TAG, privData, ERROR);
+ OicSecKey_t privKey = {privData, keySize};
- uint32_t outLen = 0;
-
- base64Buff = (char*) OICCalloc(B64ENCODE_OUT_SAFESIZE(privDataKeySize) + 1, sizeof(char));
- PM_VERIFY_NON_NULL(TAG, base64Buff, OC_STACK_NO_MEMORY, ERROR);
- int memReq = (B64ENCODE_OUT_SAFESIZE(privDataKeySize) + 1) * sizeof(char);
- B64Result b64Ret = b64Encode(privData, privDataKeySize*sizeof(uint8_t), base64Buff,
- memReq, &outLen);
- PM_VERIFY_SUCCESS(TAG, B64_OK == b64Ret, OC_STACK_ERROR, ERROR);
+ OCFillRandomMem(privData, privDataKeySize);
// TODO: currently owner array is 1. only provisioning tool's id.
- tempFirstCred = GenerateCredential(secondDeviceId, type, NULL, base64Buff, 1, ptDeviceId);
- PM_VERIFY_NON_NULL(TAG, tempFirstCred, OC_STACK_ERROR, ERROR);
+ tempFirstCred = GenerateCredential(secondDeviceId, type, NULL, &privKey, ptDeviceId);
+ VERIFY_NON_NULL(TAG, tempFirstCred, ERROR);
// TODO: currently owner array is 1. only provisioning tool's id.
- tempSecondCred = GenerateCredential(firstDeviceId, type, NULL, base64Buff, 1, ptDeviceId);
- PM_VERIFY_NON_NULL(TAG, tempSecondCred, OC_STACK_ERROR, ERROR);
+ tempSecondCred = GenerateCredential(firstDeviceId, type, NULL, &privKey, ptDeviceId);
+ VERIFY_NON_NULL(TAG, tempSecondCred, ERROR);
*firstCred = tempFirstCred;
*secondCred = tempSecondCred;
res = OC_STACK_OK;
-bail:
+exit:
OICFree(privData);
- OICFree(base64Buff);
if(res != OC_STACK_OK)
{
}
#ifdef __WITH_X509__
-/**
- * Function to compose JSON Web Key (JWK) string from a certificate and a public key.
- *
- * @param[in] certificateChain Array of Base64 encoded certificate strings.
- * @param[in] chainLength Number of the certificates in certificateChain.
- * @return Valid JWK string on success, or NULL on fail.
- */
-static char *CreateCertificatePublicJWK(const char *const *certificateChain,
- const size_t chainLength)
+static void writeCertPrefix(uint8_t *prefix, uint32_t certLen)
{
- if (NULL == certificateChain || chainLength == 0)
- {
- OIC_LOG(ERROR, TAG, "Error CreateCertificatePublicJWK: Invalid params");
- return NULL;
- }
-
- size_t certChainSize = 0;
- for (size_t i = 0; i < chainLength; ++i)
- {
- if (NULL != certificateChain[i])
- {
- certChainSize += strlen(certificateChain[i]);
- }
- else
- {
- OIC_LOG(ERROR, TAG, "Error CreateCertificatePublicJWK: Invalid params");
- return NULL;
- }
-
- }
- /* certificates in the json array taken in quotes and separated by a comma
- * so we have to count the number of characters (number of commas and quotes) required
- * for embedding certificates in the array depending on the number of certificates in chain
- * each certificate except last embeded in "\"%s\"," */
- const int numCommasAndQuotes = chainLength * 3 - 1;
- const char firstPart[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"x5c\":[";
- const char secondPart[] = "]}";
- /* to calculate the size of JWK public part we need to add the value of first and second parts,
- * size of certificate chain, number of additional commas and quotes and 1 for string termination symbol */
- size_t certPubJWKLen = strlen(firstPart) + strlen(secondPart)
- + certChainSize + numCommasAndQuotes + 1;
- char *certPubJWK = (char *)OICMalloc(certPubJWKLen);
-
- if (NULL != certPubJWK)
+ for (size_t i = 0; i < CERT_LEN_PREFIX; ++i)
{
- OICStrcpy(certPubJWK, certPubJWKLen, firstPart);
- size_t offset = strlen(firstPart);
- for (size_t i = 0; i < chainLength; ++i)
- {
- offset += snprintf(certPubJWK + offset, certPubJWKLen - offset, "\"%s\",", certificateChain[i]);
- }
- snprintf(certPubJWK + offset - 1, certPubJWK - offset - 1, secondPart);
- }
- else
- {
- OIC_LOG(ERROR, TAG, "Error while memory allocation");
+ prefix[i] = (certLen >> (BYTE_SIZE * (CERT_LEN_PREFIX - 1 - i))) & 0xFF;
}
- return certPubJWK;
}
-/**
- * Function to compose JWK string from a private key.
- *
- * @param[in] privateKey Base64 encoded private key.
- * @return Valid JWK string on success, or NULL on fail.
- */
-static char *CreateCertificatePrivateJWK(const char *privateKey)
+static uint32_t appendCert2Chain(uint8_t *appendPoint, uint8_t *cert, size_t len)
{
- if (NULL == privateKey)
- {
- OIC_LOG(ERROR, TAG, "Error privateKey is NULL");
- return NULL;
- }
- const char firstPart[] = "{\"kty\":\"EC\",\"crv\":\"P-256\",\"d\":\"";
- const char secondPart[] = "\"}";
- size_t len = strlen(firstPart) + strlen(secondPart) + strlen(privateKey) + 1;
- char *certPrivJWK = (char *)OICMalloc(len);
+ uint32_t ret = 0;
+ VERIFY_NON_NULL(TAG, appendPoint, ERROR);
+ VERIFY_NON_NULL(TAG, cert, ERROR);
- if (NULL != certPrivJWK)
- {
- snprintf(certPrivJWK, len, "%s%s%s", firstPart, privateKey, secondPart);
- }
- else
- {
- OIC_LOG(ERROR, TAG, "Error while memory allocation");
- }
- return certPrivJWK;
-}
+ memcpy(appendPoint + CERT_LEN_PREFIX, cert, len);
+ writeCertPrefix(appendPoint, len);
+ ret = len + CERT_LEN_PREFIX;
+exit:
+ return ret;
+}
/**
* Function to generate Base64 encoded credential data for device.
* @param[out] privKey Pointer to Base64 encoded private key.
* @return OC_STACK_OK on success
*/
-static OCStackResult GenerateCertificateAndKeys(const OicUuid_t * subject, char *** const certificateChain,
- size_t * const chainLength, char ** const privKey)
+static OCStackResult GenerateCertificateAndKeys(const OicUuid_t * subject, OicSecCert_t * certificateChain,
+ OicSecKey_t * privKey)
{
- if (NULL == subject || NULL == certificateChain || NULL == chainLength || NULL == privKey)
+ if (NULL == subject || NULL == certificateChain || NULL == privKey)
{
return OC_STACK_INVALID_PARAM;
}
- *certificateChain = NULL;
- *privKey = NULL;
+ certificateChain->data = NULL;
+ privKey->data = NULL;
ByteArray pubKeyBA = BYTE_ARRAY_INITIALIZER;
ByteArray privKeyBA = BYTE_ARRAY_INITIALIZER;
return OC_STACK_ERROR;
}
- char privB64buf[B64ENCODE_OUT_SAFESIZE(PRIVATE_KEY_SIZE) + 1] = {0};
- uint32_t privB64len = 0;
- if (B64_OK != b64Encode(privKeyBA.data, privKeyBA.len, privB64buf,
- B64ENCODE_OUT_SAFESIZE(PRIVATE_KEY_SIZE) + 1, &privB64len))
- {
- OIC_LOG(ERROR, TAG, "Error while encoding key");
- return OC_STACK_ERROR;
- }
-
- if (PKI_SUCCESS != GetCAChain(chainLength , cert + 1))
+ uint8_t numCert = 0;
+ if (PKI_SUCCESS != GetCAChain(&numCert , cert + 1))
{
OIC_LOG(ERROR, TAG, "Error getting CA certificate chain.");
return OC_STACK_ERROR;
}
- ++(*chainLength);
- *certificateChain = (char **)OICMalloc(sizeof(char *) * (*chainLength));
-
- OCStackResult ret = OC_STACK_NO_MEMORY;
- if (NULL == *certificateChain)
- {
- goto memclean;
- }
-
-
- for (size_t i = 0; i < *chainLength; ++i)
+ numCert ++;
+ uint32_t len = 0;
+ for (size_t i = 0; i < numCert; i++)
{
- (*certificateChain)[i] = NULL;
-
- char certB64buf[B64ENCODE_OUT_SAFESIZE(ISSUER_MAX_CERT_SIZE) + 1] = {0};
- uint32_t certB64len = 0;
- if (B64_OK != b64Encode(cert[i].data, cert[i].len, certB64buf,
- B64ENCODE_OUT_SAFESIZE(ISSUER_MAX_CERT_SIZE) + 1, &certB64len))
+ certificateChain->data = (uint8_t *) OICRealloc(certificateChain->data,
+ len + cert[i].len + CERT_LEN_PREFIX);
+ if (NULL == certificateChain->data)
{
- OIC_LOG(ERROR, TAG, "Error while encoding certificate");
- ret = OC_STACK_ERROR;
- goto memclean;
+ OIC_LOG(ERROR, TAG, "Error while memory allocation");
+ return OC_STACK_ERROR;
}
- (*certificateChain)[i] = (char *) OICMalloc(certB64len + 1);
- if (NULL == (*certificateChain)[i])
+ uint32_t appendedLen = appendCert2Chain(certificateChain->data + len,
+ cert[i].data, cert[i].len);
+ if (0 == appendedLen)
{
- goto memclean;
+ OIC_LOG(ERROR, TAG, "Error while certifiacate chain creation.");
+ OICFree(certificateChain->data);
+ certificateChain->len = 0;
+ return OC_STACK_ERROR;
}
-
- memcpy((*certificateChain)[i], certB64buf, certB64len + 1);
+ len += appendedLen;
}
-
-
- *privKey = (char *)OICMalloc(privB64len + 1);
-
- if (NULL == *privKey)
+ certificateChain->len = len;
+ privKey->data = (uint8_t*) OICMalloc(PRIVATE_KEY_SIZE);
+ if (NULL == privKey->data)
{
-memclean:
- if (NULL != *certificateChain)
- {
- for (size_t i = 0; i < *chainLength; ++i)
- {
- OICFree((*certificateChain)[i]);
- }
- }
- OICFree(*certificateChain);
- *certificateChain = NULL;
- *privKey = NULL;
- *chainLength = 0;
- if (OC_STACK_NO_MEMORY == ret)
- {
- OIC_LOG(ERROR, TAG, "Error while memory allocation");
- }
- return ret;
+ OIC_LOG(ERROR, TAG, "Error while memory allocation");
+ OICFree(certificateChain->data);
+ certificateChain->len = 0;
+ privKey->len = 0;
+ return OC_STACK_ERROR;
}
-
- memcpy(*privKey, privB64buf, privB64len + 1);
+ memcpy(privKey->data, privKeyData, PRIVATE_KEY_SIZE);
+ privKey->len = PRIVATE_KEY_SIZE;
return OC_STACK_OK;
}
-
OCStackResult PMGenerateCertificateCredentials(const OicUuid_t *ptDeviceId,
const OicUuid_t *deviceId, OicSecCred_t **const cred)
{
{
return OC_STACK_INVALID_PARAM;
}
- char **certificateChain = NULL;
- char *privKey = NULL;
- size_t certChainLen = 0;
- if (OC_STACK_OK != GenerateCertificateAndKeys(deviceId, &certificateChain,
- &certChainLen, &privKey))
+ OicSecCert_t certificateChain;
+ OicSecKey_t privKey;
+ if (OC_STACK_OK != GenerateCertificateAndKeys(deviceId, &certificateChain, &privKey))
{
OIC_LOG(ERROR, TAG, "Error while generating credential data.");
return OC_STACK_ERROR;
}
- char *publicJWK = CreateCertificatePublicJWK(certificateChain, certChainLen);
- char *privateJWK = CreateCertificatePrivateJWK(privKey);
- for (size_t i = 0; i < certChainLen; ++i)
- {
- OICFree(certificateChain[i]);
- }
- OICFree(certificateChain);
- OICFree(privKey);
- if (NULL == publicJWK || NULL == privateJWK)
- {
- OICFree(publicJWK);
- OICFree(privateJWK);
- OIC_LOG(ERROR, TAG, "Error while converting keys to JWK format.");
- return OC_STACK_ERROR;
- }
-
- OicSecCred_t *tempCred = GenerateCredential(deviceId, SIGNED_ASYMMETRIC_KEY, publicJWK,
- privateJWK, 1, ptDeviceId);
- OICFree(publicJWK);
- OICFree(privateJWK);
- if (NULL == tempCred)
- {
- OIC_LOG(ERROR, TAG, "Error while generating credential.");
- return OC_STACK_ERROR;
- }
- *cred = tempCred;
+ *cred = GenerateCredential(deviceId, SIGNED_ASYMMETRIC_KEY, &certificateChain,
+ &privKey, ptDeviceId);
return OC_STACK_OK;
}
#endif // __WITH_X509__
* OCMode.
*
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from
- * client before returning the list of devices.
+ * server before returning the list of devices.
* @param[out] ppList List of candidate devices to be provisioned
* @return OTM_SUCCESS in case of success and other value otherwise.
*/
* all the device in subnet which are owned by calling provisioning client.
*
* @param[in] timeout Timeout in seconds, value till which function will listen to responses from
- * client before returning the list of devices.
+ * server before returning the list of devices.
* @param[out] ppList List of device owned by provisioning tool.
* @return OTM_SUCCESS in case of success and other value otherwise.
*/
{
if(NULL == callbackData)
{
- return OC_STACK_INVALID_PARAM;
+ return OC_STACK_INVALID_CALLBACK ;
}
return OTMSetOwnershipTransferCallbackData(oxm, callbackData);
{
return OC_STACK_INVALID_PARAM;
}
-
+ if (!resultCallback)
+ {
+ OIC_LOG(INFO, TAG, "OCDoOwnershipTransfer : NULL Callback");
+ return OC_STACK_INVALID_CALLBACK;
+ }
return OTMDoOwnershipTransfer(ctx, targetDevices, resultCallback);
}
OCUuidList_t* idList = NULL;
size_t numOfDev = 0;
- if (!pTargetDev1 || !pTargetDev2 || !resultCallback)
+ if (!pTargetDev1 || !pTargetDev2 || !pTargetDev1->doxm || !pTargetDev2->doxm)
{
OIC_LOG(ERROR, TAG, "OCUnlinkDevices : NULL parameters");
return OC_STACK_INVALID_PARAM;
}
+ if (!resultCallback)
+ {
+ OIC_LOG(INFO, TAG, "OCUnlinkDevices : NULL Callback");
+ return OC_STACK_INVALID_CALLBACK;
+ }
+ if (0 == memcmp(&pTargetDev1->doxm->deviceID, &pTargetDev2->doxm->deviceID, sizeof(OicUuid_t)))
+ {
+ OIC_LOG(INFO, TAG, "OCUnlinkDevices : Same device ID");
+ return OC_STACK_INVALID_PARAM;
+ }
// Get linked devices with the first device.
OCStackResult res = PDMGetLinkedDevices(&(pTargetDev1->doxm->deviceID), &idList, &numOfDev);
{
OIC_LOG(INFO, TAG, "IN OCRemoveDevice");
OCStackResult res = OC_STACK_ERROR;
- if (!pTargetDev || !resultCallback || 0 == waitTimeForOwnedDeviceDiscovery)
+ if (!pTargetDev || 0 == waitTimeForOwnedDeviceDiscovery)
{
OIC_LOG(INFO, TAG, "OCRemoveDevice : Invalied parameters");
return OC_STACK_INVALID_PARAM;
}
+ if (!resultCallback)
+ {
+ OIC_LOG(INFO, TAG, "OCRemoveDevice : NULL Callback");
+ return OC_STACK_INVALID_CALLBACK;
+ }
// Send DELETE requests to linked devices
OCStackResult resReq = OC_STACK_ERROR; // Check that we have to wait callback or not.
OCProvisionResultCB resultCallback)
{
- if (!pDev1 || !pDev2 || !resultCallback)
+ if (!pDev1 || !pDev2 || !pDev1->doxm || !pDev2->doxm)
{
OIC_LOG(ERROR, TAG, "OCProvisionPairwiseDevices : Invalid parameters");
return OC_STACK_INVALID_PARAM;
}
+ if (!resultCallback)
+ {
+ OIC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : NULL Callback");
+ return OC_STACK_INVALID_CALLBACK;
+ }
if (!(keySize == OWNER_PSK_LENGTH_128 || keySize == OWNER_PSK_LENGTH_256))
{
OIC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : Invalid key size");
return OC_STACK_INVALID_PARAM;
}
+ if (0 == memcmp(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, sizeof(OicUuid_t)))
+ {
+ OIC_LOG(INFO, TAG, "OCProvisionPairwiseDevices : Same device ID");
+ return OC_STACK_INVALID_PARAM;
+ }
OIC_LOG(DEBUG, TAG, "Checking link in DB");
bool linkExists = true;
#include "srmutility.h"
#include "provisioningdatabasemanager.h"
#include "oxmrandompin.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
#define TAG "OTM"
static OTMCallbackData_t g_OTMDatas[OIC_OXM_COUNT];
/**
- * Variable for storing provisioning tool's provisioning capabilities
- * Must be in decreasing order of preference. More prefered method should
- * have lower array index.
- */
-static OicSecDpom_t gProvisioningToolCapability[] = { SINGLE_SERVICE_CLIENT_DRIVEN };
-
-/**
- * Number of supported provisioning methods
- * current version supports only one.
- */
-static size_t gNumOfProvisioningMethodsPT = 1;
-
-/**
* Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
*/
static OTMContext_t* g_otmCtx = NULL;
* @return OC_STACK_OK on success
*/
static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
- size_t numberOfMethods,
- OicSecOxm_t *selectedMethod)
+ size_t numberOfMethods, OicSecOxm_t *selectedMethod)
{
OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
OicSecDpom_t *selectedMode)
{
OIC_LOG(DEBUG, TAG, "IN SelectOperationMode");
-
- size_t i = 0;
- size_t j = 0;
-
- while (i < gNumOfProvisioningMethodsPT && j < selectedDeviceInfo->pstat->smLen)
- {
- if (gProvisioningToolCapability[i] < selectedDeviceInfo->pstat->sm[j])
- {
- i++;
- }
- else if (selectedDeviceInfo->pstat->sm[j] < gProvisioningToolCapability[i])
- {
- j++;
- }
- else /* if gProvisioningToolCapability[i] == deviceSupportedMethods[j] */
- {
- *selectedMode = gProvisioningToolCapability[j];
- break;
- }
- }
+ *selectedMode = selectedDeviceInfo->pstat->sm[0];
OIC_LOG_V(DEBUG, TAG, "Selected Operation Mode = %d", *selectedMode);
-
- OIC_LOG(DEBUG, TAG, "OUT SelectOperationMode");
}
/**
static OCStackResult PutOwnershipInformation(OTMContext_t* otmCtx);
/**
- * Function to update pstat when finalize provisioning.
- * This function would update 'cm' as bx0011,1100 and 'tm' as bx0000,0000.
+ * Function to update pstat as Ready for provisioning.
+ * This function would update 'cm' from bx0000,0010 to bx0000,0000.
*
* @param[in] ctx context value passed to callback from calling function.
* @param[in] selectedDevice selected device information to performing provisioning.
*/
static OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx);
+/**
+ * Function to update pstat as Ready for Normal Operation.
+ * This function would update 'isop' from false to true.
+ *
+ * @param[in] ctx context value passed to callback from calling function.
+ * @param[in] selectedDevice selected device information to performing provisioning.
+ * @return OC_STACK_OK on success
+ */
+static OCStackResult PutNormalOperationStatus(OTMContext_t* otmCtx);
+
static bool IsComplete(OTMContext_t* otmCtx)
{
for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++)
}
uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
+ OicSecKey_t ownerKey = {ownerPSK, OWNER_PSK_LENGTH_128};
//Generating OwnerPSK
CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
OIC_LOG(INFO, TAG,"ownerPSK dump:\n");
OIC_LOG_BUFFER(INFO, TAG,ownerPSK, OWNER_PSK_LENGTH_128);
//Generating new credential for provisioning tool
- size_t ownLen = 1;
- uint32_t outLen = 0;
-
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {};
- B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff),
- &outLen);
- VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
-
OicSecCred_t *cred = GenerateCredential(&selectedDeviceInfo->doxm->deviceID,
SYMMETRIC_PAIR_WISE_KEY, NULL,
- base64Buff, ownLen, &ptDeviceID);
+ &ownerKey, &ptDeviceID);
VERIFY_NON_NULL(TAG, cred, ERROR);
res = AddCredential(cred);
SetResult(otmCtx, OC_STACK_ERROR);
return OC_STACK_DELETE_TRANSACTION;
}
-
- OicSecPstat_t* pstat = JSONToPstatBin(
- ((OCSecurityPayload*)clientResponse->payload)->securityData);
- if(NULL == pstat)
+ OicSecPstat_t* pstat = NULL;
+ OCStackResult result = CBORPayloadToPstat(
+ ((OCSecurityPayload*)clientResponse->payload)->securityData,
+ ((OCSecurityPayload*)clientResponse->payload)->payloadSize,
+ &pstat);
+ if(NULL == pstat || result != OC_STACK_OK)
{
- OIC_LOG(ERROR, TAG, "Error while converting json to pstat bin");
+ OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
+ SetResult(otmCtx, OC_STACK_ERROR);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ if(false == (TAKE_OWNER & pstat->cm))
+ {
+ OIC_LOG(ERROR, TAG, "Device pairing mode enabling owner transfer operations is disabled");
SetResult(otmCtx, OC_STACK_ERROR);
return OC_STACK_DELETE_TRANSACTION;
}
if(otmCtx && otmCtx->selectedDeviceInfo)
{
OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
- OIC_LOG(INFO, TAG, "Start defualt ACL & commit-hash provisioning.");
+ OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
res = PutProvisioningStatus(otmCtx);
if(OC_STACK_OK != res)
OTMContext_t* otmCtx = (OTMContext_t*) ctx;
(void)UNUSED;
+ OCStackResult res = OC_STACK_OK;
+
+ if(OC_STACK_OK == clientResponse->result)
+ {
+ if(otmCtx && otmCtx->selectedDeviceInfo)
+ {
+ OIC_LOG(INFO, TAG, "Device state is in Ready for Provisionig.");
+
+ res = PutNormalOperationStatus(otmCtx);
+ if(OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to update pstat");
+ SetResult(otmCtx, res);
+ }
+ }
+ }
+ else
+ {
+ OIC_LOG_V(INFO, TAG, "Error occured in provisionDefaultACLCB :: %d\n",
+ clientResponse->result);
+ SetResult(otmCtx, clientResponse->result);
+ }
+
+exit:
+ OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+/**
+ * Response handler of update provisioning status to Ready for Normal..
+ *
+ * @param[in] ctx ctx value passed to callback from calling function.
+ * @param[in] UNUSED handle to an invocation
+ * @param[in] clientResponse Response from queries to remote servers.
+ * @return OC_STACK_DELETE_TRANSACTION to delete the transaction
+ * and OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult ReadyForNomalStatusHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse)
+{
+ OIC_LOG_V(INFO, TAG, "IN ReadyForNomalStatusHandler.");
+
+ VERIFY_NON_NULL(TAG, clientResponse, ERROR);
+ VERIFY_NON_NULL(TAG, ctx, ERROR);
+
+ OTMContext_t* otmCtx = (OTMContext_t*) ctx;
+ (void)UNUSED;
if (OC_STACK_OK == clientResponse->result)
{
+ OIC_LOG(INFO, TAG, "Device state is in Ready for Normal Operation.");
OCStackResult res = PDMAddDevice(&otmCtx->selectedDeviceInfo->doxm->deviceID);
if (OC_STACK_OK == res)
{
SetResult(otmCtx, clientResponse->result);
}
-
exit:
- OIC_LOG_V(INFO, TAG, "OUT ProvisioningStatusHandler.");
+ OIC_LOG_V(INFO, TAG, "OUT ReadyForNomalStatusHandler.");
return OC_STACK_DELETE_TRANSACTION;
}
//Generate owner credential for new device
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- OicSecCred_t* ownerCredential =
- GetCredResourceData(&(deviceInfo->doxm->deviceID));
+ const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
if(!ownerCredential)
{
OIC_LOG(ERROR, TAG, "Can not find OwnerPSK.");
//Fill private data as empty string
newCredential.privateData.data = NULL;
+ newCredential.privateData.len = 0;
+#ifdef __WITH_X509__
+ newCredential.publicData.data = NULL;
+ newCredential.publicData.len = 0;
+#endif
//Send owner credential to new device : PUT /oic/sec/cred [ owner credential ]
- secPayload->securityData = BinToCredJSON(&newCredential);
- if (NULL == secPayload->securityData)
+ if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData, &secPayload->payloadSize))
{
OICFree(secPayload);
- OIC_LOG(ERROR, TAG, "Error while converting bin to json");
+ OIC_LOG(ERROR, TAG, "Error while converting bin to cbor.");
return OC_STACK_ERROR;
}
- OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData);
+ OIC_LOG(DEBUG, TAG, "Cred Payload:");
+ OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
OCCallbackData cbData;
cbData.cb = &OwnerCredentialHandler;
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = g_OTMDatas[selectedOxm].createSelectOxmPayloadCB(otmCtx);
- if (NULL == secPayload->securityData)
+ OCStackResult res = g_OTMDatas[selectedOxm].createSelectOxmPayloadCB(otmCtx,
+ &secPayload->securityData, &secPayload->payloadSize);
+ if (OC_STACK_OK != res && NULL == secPayload->securityData)
{
- OICFree(secPayload);
- OIC_LOG(ERROR, TAG, "Error while converting bin to json");
+ OCPayloadDestroy((OCPayload *)secPayload);
+ OIC_LOG(ERROR, TAG, "Error while converting bin to cbor");
return OC_STACK_ERROR;
}
cbData.cb = &OwnerTransferModeHandler;
cbData.context = (void *)otmCtx;
cbData.cd = NULL;
- OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query,
- &deviceInfo->endpoint, (OCPayload*)secPayload,
- deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ res = OCDoResource(NULL, OC_REST_PUT, query,
+ &deviceInfo->endpoint, (OCPayload *)secPayload,
+ deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
if (res != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "OCStack resource error");
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData =
- g_OTMDatas[deviceInfo->doxm->oxmSel].createOwnerTransferPayloadCB(otmCtx);
- if (NULL == secPayload->securityData)
+ OCStackResult res = g_OTMDatas[deviceInfo->doxm->oxmSel].createOwnerTransferPayloadCB(
+ otmCtx, &secPayload->securityData, &secPayload->payloadSize);
+ if (OC_STACK_OK != res && NULL == secPayload->securityData)
{
- OICFree(secPayload);
- OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
+ OCPayloadDestroy((OCPayload *)secPayload);
+ OIC_LOG(ERROR, TAG, "Error while converting doxm bin to cbor.");
return OC_STACK_INVALID_PARAM;
}
- OIC_LOG_V(DEBUG, TAG, "Payload : %s", secPayload->securityData);
+ OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
OCCallbackData cbData;
cbData.cb = &OwnerUuidUpdateHandler;
cbData.context = (void *)otmCtx;
cbData.cd = NULL;
- OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
- deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload *)secPayload,
+ deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
if (res != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "OCStack resource error");
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
//OwnershipInformationHandler
- OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
- if(!secPayload)
+ OCSecurityPayload *secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
+ if (!secPayload)
{
OIC_LOG(ERROR, TAG, "Failed to memory allocation");
return OC_STACK_NO_MEMORY;
}
otmCtx->selectedDeviceInfo->doxm->owned = true;
- secPayload->securityData = BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
- if (NULL == secPayload->securityData)
+
+ secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+ OCStackResult res = DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm,
+ &secPayload->securityData, &secPayload->payloadSize);
+ if (OC_STACK_OK != res && NULL == secPayload->securityData)
{
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "Error while converting doxm bin to json");
return OC_STACK_INVALID_PARAM;
}
- secPayload->base.type = PAYLOAD_TYPE_SECURITY;
OCCallbackData cbData;
cbData.cb = &OwnershipInformationHandler;
cbData.context = (void *)otmCtx;
cbData.cd = NULL;
- OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
- deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
+ deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
if (res != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "OCStack resource error");
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToPstatJSON(deviceInfo->pstat);
- if (NULL == secPayload->securityData)
+ OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
+ &secPayload->payloadSize);
+ if (OC_STACK_OK != res)
{
- OICFree(secPayload);
- OIC_LOG(ERROR, TAG, "Error while converting pstat bin to json");
+ OCPayloadDestroy((OCPayload *)secPayload);
+ OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
return OC_STACK_INVALID_PARAM;
}
cbData.cb = &OperationModeUpdateHandler;
cbData.context = (void *)otmCtx;
cbData.cd = NULL;
- OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
- deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload *)secPayload,
+ deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
if (res != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "OCStack resource error");
OICFree(otmCtx->ctxResultArray);
OICFree(otmCtx);
return res;
-
}
OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx)
{
OIC_LOG(INFO, TAG, "IN PutProvisioningStatus");
- if(!otmCtx)
+ if(!otmCtx || !otmCtx->selectedDeviceInfo)
{
OIC_LOG(ERROR, TAG, "OTMContext is NULL");
return OC_STACK_INVALID_PARAM;
}
- if(!otmCtx->selectedDeviceInfo)
- {
- OIC_LOG(ERROR, TAG, "Can't find device information in OTMContext");
- OICFree(otmCtx);
- return OC_STACK_INVALID_PARAM;
- }
- otmCtx->selectedDeviceInfo->pstat->tm = NORMAL;
- otmCtx->selectedDeviceInfo->pstat->cm = PROVISION_ACLS | PROVISION_CREDENTIALS |
- SECURITY_MANAGEMENT_SERVICES | BOOTSTRAP_SERVICE;
- OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
- if(!secPayload)
+ //Change the TAKE_OWNER bit of CM to 0.
+ otmCtx->selectedDeviceInfo->pstat->cm &= (~TAKE_OWNER);
+
+ OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
+ if (!secPayload)
{
OIC_LOG(ERROR, TAG, "Failed to memory allocation");
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToPstatJSON(otmCtx->selectedDeviceInfo->pstat);
- if (NULL == secPayload->securityData)
+ if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
+ &secPayload->securityData, &secPayload->payloadSize))
{
- OICFree(secPayload);
- SetResult(otmCtx, OC_STACK_INVALID_JSON);
+ OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_INVALID_JSON;
}
- OIC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData);
+ OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
+ OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
if(!PMGenerateQuery(true,
if (ret != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "OCStack resource error");
- SetResult(otmCtx, ret);
}
OIC_LOG(INFO, TAG, "OUT PutProvisioningStatus");
return ret;
}
+OCStackResult PutNormalOperationStatus(OTMContext_t* otmCtx)
+{
+ OIC_LOG(INFO, TAG, "IN PutNormalOperationStatus");
+
+ if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ {
+ OIC_LOG(ERROR, TAG, "OTMContext is NULL");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ //Set isop to true.
+ otmCtx->selectedDeviceInfo->pstat->isOp = true;
+
+ OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
+ if (!secPayload)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to memory allocation");
+ return OC_STACK_NO_MEMORY;
+ }
+ secPayload->base.type = PAYLOAD_TYPE_SECURITY;
+ if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
+ &secPayload->securityData, &secPayload->payloadSize))
+ {
+ OCPayloadDestroy((OCPayload *)secPayload);
+ return OC_STACK_INVALID_JSON;
+ }
+ OIC_LOG(DEBUG, TAG, "Created payload for chage to Provisiong state");
+ OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
+ char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+ if(!PMGenerateQuery(true,
+ otmCtx->selectedDeviceInfo->endpoint.addr,
+ otmCtx->selectedDeviceInfo->securePort,
+ otmCtx->selectedDeviceInfo->connType,
+ query, sizeof(query), OIC_RSRC_PSTAT_URI))
+ {
+ OIC_LOG(ERROR, TAG, "PutNormalOperationStatus : Failed to generate query");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+ OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
+ cbData.cb = &ReadyForNomalStatusHandler;
+ cbData.context = (void*)otmCtx;
+ cbData.cd = NULL;
+ OCStackResult ret = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
+ otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+ OIC_LOG_V(INFO, TAG, "OCDoResource returned: %d",ret);
+ if (ret != OC_STACK_OK)
+ {
+ OIC_LOG(ERROR, TAG, "OCStack resource error");
+ }
+
+ OIC_LOG(INFO, TAG, "OUT PutNormalOperationStatus");
+
+ return ret;
+}
#define TAG "OXM_JustWorks"
-char* CreateJustWorksSelectOxmPayload(OTMContext_t* otmCtx)
+OCStackResult CreateJustWorksSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **payload, size_t *size)
{
- if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ if (!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_JUST_WORKS;
- return BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
+ *payload = NULL;
+ *size = 0;
+
+ return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size);
}
-char* CreateJustWorksOwnerTransferPayload(OTMContext_t* otmCtx)
+OCStackResult CreateJustWorksOwnerTransferPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
{
- if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ if (!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
OicUuid_t uuidPT = {.id={0}};
if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
{
OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
- return NULL;
+ return OC_STACK_ERROR;
}
memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id , UUID_LENGTH);
- return BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
+ *payload = NULL;
+ *size = 0;
+
+ return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size);
}
OCStackResult LoadSecretJustWorksCallback(OTMContext_t* UNUSED_PARAM)
OCStackResult CreateSecureSessionJustWorksCallback(OTMContext_t* otmCtx)
{
OIC_LOG(INFO, TAG, "IN CreateSecureSessionJustWorksCallback");
- if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ if (!otmCtx || !otmCtx->selectedDeviceInfo)
{
return OC_STACK_INVALID_PARAM;
}
}
OIC_LOG(INFO, TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 cipher suite selected.");
- OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
+ OCProvisionDev_t *selDevInfo = otmCtx->selectedDeviceInfo;
CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
if(NULL == endpoint)
{
return OC_STACK_NO_MEMORY;
}
- memcpy(endpoint,&selDevInfo->endpoint,sizeof(CAEndpoint_t));
+ memcpy(endpoint, &selDevInfo->endpoint, sizeof(CAEndpoint_t));
endpoint->port = selDevInfo->securePort;
caresult = CAInitiateHandshake(endpoint);
#define TAG "OXM_RandomPIN"
-char* CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx)
+OCStackResult CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
{
- if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_RANDOM_DEVICE_PIN;
- return BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
+ return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size);
}
-char* CreatePinBasedOwnerTransferPayload(OTMContext_t* otmCtx)
+OCStackResult CreatePinBasedOwnerTransferPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
{
- if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
OicUuid_t uuidPT = {.id={0}};
+ *payload = NULL;
+ *size = 0;
if (OC_STACK_OK != GetDoxmDeviceID(&uuidPT))
{
OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
- return NULL;
+ return OC_STACK_ERROR;
}
memcpy(otmCtx->selectedDeviceInfo->doxm->owner.id, uuidPT.id , UUID_LENGTH);
- return BinToDoxmJSON(otmCtx->selectedDeviceInfo->doxm);
+ return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size);
}
-OCStackResult InputPinCodeCallback(OTMContext_t* otmCtx)
+OCStackResult InputPinCodeCallback(OTMContext_t *otmCtx)
{
- if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ if (!otmCtx || !otmCtx->selectedDeviceInfo)
{
return OC_STACK_INVALID_PARAM;
}
uint8_t pinData[OXM_RANDOM_PIN_SIZE + 1];
OCStackResult res = InputPin((char*)pinData, OXM_RANDOM_PIN_SIZE + 1);
- if(OC_STACK_OK != res)
+ if (OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Failed to input PIN");
return res;
return res;
}
-OCStackResult CreateSecureSessionRandomPinCallbak(OTMContext_t* otmCtx)
+OCStackResult CreateSecureSessionRandomPinCallback(OTMContext_t* otmCtx)
{
OIC_LOG(INFO, TAG, "IN CreateSecureSessionRandomPinCallbak");
- if(!otmCtx || !otmCtx->selectedDeviceInfo)
+ if (!otmCtx || !otmCtx->selectedDeviceInfo)
{
return OC_STACK_INVALID_PARAM;
}
}
OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 cipher suite selected.");
-
OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
- if(NULL == endpoint)
+ if (NULL == endpoint)
{
return OC_STACK_NO_MEMORY;
}
return OC_STACK_OK;
}
-
#include "srmresourcestrings.h" //@note: SRM's internal header
#include "doxmresource.h" //@note: SRM's internal header
#include "pstatresource.h" //@note: SRM's internal header
+#include "verresource.h" //@note: SRM's internal header
#include "pmtypes.h"
#include "pmutility.h"
bool isOwnedDiscovery;
} DiscoveryInfo;
+/*
+ * Function to discover secre port information through unicast
+ *
+ * @param[in] discoveryInfo The pointer of discovery information to matain result of discovery
+ * @param[in] clientResponse Response information(It will contain payload)
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse);
+
+/*
+ * Function to discover security version information through unicast
+ *
+ * @param[in] discoveryInfo The pointer of discovery information to matain result of discovery
+ * @param[in] clientResponse Response information(It will contain payload)
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse);
+
+/**
+ * Callback handler for PMDeviceDiscovery API.
+ *
+ * @param[in] ctx User context
+ * @param[in] handle Handler for response
+ * @param[in] clientResponse Response information (It will contain payload)
+ * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
+ * OC_STACK_DELETE_TRANSACTION to delete it.
+ */
+static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse);
+
+/**
+ * Callback handler for getting secure port information using /oic/res discovery.
+ *
+ * @param[in] ctx user context
+ * @param[in] handle Handle for response
+ * @param[in] clientResponse Response information(It will contain payload)
+ *
+ * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
+ * OC_STACK_DELETE_TRANSACTION to delete it.
+ */
+static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse);
+
+/**
+ * Callback handler for security version discovery.
+ *
+ * @param[in] ctx User context
+ * @param[in] handle Handler for response
+ * @param[in] clientResponse Response information (It will contain payload)
+ * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
+ * OC_STACK_DELETE_TRANSACTION to delete it.
+ */
+static OCStackApplicationResult SecVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse);
+
/**
* Function to search node in linked list that matches given IP and port.
*
ptr->next = NULL;
ptr->connType = connType;
ptr->devStatus = DEV_STATUS_ON; //AddDevice is called when discovery(=alive)
+ OICStrcpy(ptr->secVer, MAX_VERSION_LEN, DEFAULT_SEC_VERSION); // version initialization
LL_PREPEND(*ppDevicesList, ptr);
}
}
/**
+ * Function to set security version information from the given list of devices.
+ *
+ * @param[in] pList List of OCProvisionDev_t.
+ * @param[in] addr address of target device.
+ * @param[in] port port of remote server.
+ * @param[in] secVer security version information.
+ *
+ * @return OC_STACK_OK for success and errorcode otherwise.
+ */
+OCStackResult UpdateSecVersionOfDevice(OCProvisionDev_t **ppDevicesList, const char *addr,
+ uint16_t port, const char* secVer)
+{
+ if (NULL == secVer)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCProvisionDev_t *ptr = GetDevice(ppDevicesList, addr, port);
+
+ if(!ptr)
+ {
+ OIC_LOG(ERROR, TAG, "Can not find device information in the discovery device list");
+ return OC_STACK_ERROR;
+ }
+
+ OICStrcpy(ptr->secVer, MAX_VERSION_LEN, secVer);
+
+ return OC_STACK_OK;
+}
+
+/**
* This function deletes list of provision target devices
*
* @param[in] pDevicesList List of OCProvisionDev_t.
newDev->doxm->oxm = NULL;
}
+ if (0 == strlen(src->secVer))
+ {
+ OICStrcpy(newDev->secVer, MAX_VERSION_LEN, DEFAULT_SEC_VERSION);
+ }
+ else
+ {
+ OICStrcpy(newDev->secVer, MAX_VERSION_LEN, src->secVer);
+ }
+
newDev->securePort = src->securePort;
newDev->devStatus = src->devStatus;
newDev->connType = src->connType;
return true;
}
-/**
- * Callback handler for getting secure port information using /oic/res discovery.
- *
- * @param[in] ctx user context
- * @param[in] handle Handle for response
- * @param[in] clientResponse Response information(It will contain payload)
- *
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
- * OC_STACK_DELETE_TRANSACTION to delete it.
- */
+static OCStackApplicationResult SecurityVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
+ OCClientResponse *clientResponse)
+{
+ if (ctx == NULL)
+ {
+ OIC_LOG(ERROR, TAG, "Lost List of device information");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ (void)UNUSED;
+ if (clientResponse)
+ {
+ if (NULL == clientResponse->payload)
+ {
+ OIC_LOG(INFO, TAG, "Skiping Null payload");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ if (OC_STACK_OK != clientResponse->result)
+ {
+ OIC_LOG(INFO, TAG, "Error in response");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ else
+ {
+ if (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)
+ {
+ OIC_LOG(INFO, TAG, "Unknown payload type");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ OicSecVer_t *ptrVer = NULL;
+ uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
+ size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
+
+ OCStackResult res = CBORPayloadToVer(payload, size, &ptrVer);
+ if ((NULL == ptrVer) && (OC_STACK_OK != res))
+ {
+ OIC_LOG(INFO, TAG, "Ignoring malformed CBOR");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+ else
+ {
+ OIC_LOG(DEBUG, TAG, "Successfully converted ver cbor to bin.");
+
+ //If this is owend device discovery we have to filter out the responses.
+ DiscoveryInfo* pDInfo = (DiscoveryInfo*)ctx;
+ res = UpdateSecVersionOfDevice(pDInfo->ppDevicesList, clientResponse->devAddr.addr,
+ clientResponse->devAddr.port, ptrVer->secv);
+ if (OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Error while getting security version.");
+ DeleteVerBinData(ptrVer);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ OIC_LOG(INFO, TAG, "= Discovered security version =");
+ OIC_LOG_V(DEBUG, TAG, "IP %s", clientResponse->devAddr.addr);
+ OIC_LOG_V(DEBUG, TAG, "PORT %d", clientResponse->devAddr.port);
+ OIC_LOG_V(DEBUG, TAG, "VERSION %s", ptrVer->secv);
+
+ OIC_LOG(INFO, TAG, "Exiting SecVersionDiscoveryHandler.");
+ DeleteVerBinData(ptrVer);
+ }
+ }
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "Skiping Null response");
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
}
DiscoveryInfo* pDInfo = (DiscoveryInfo*)ctx;
- OCProvisionDev_t **ppDevicesList = pDInfo->ppDevicesList;
-
- OCStackResult res = UpdateSecurePortOfDevice(ppDevicesList, clientResponse->devAddr.addr,
+ OCStackResult res = UpdateSecurePortOfDevice(pDInfo->ppDevicesList,
+ clientResponse->devAddr.addr,
clientResponse->devAddr.port, securePort);
if (OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Error while getting secure port.");
return OC_STACK_DELETE_TRANSACTION;
}
+
+ res = SecurityVersionDiscovery(pDInfo, clientResponse);
+ if(OC_STACK_OK != res)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to SecurityVersionDiscovery");
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
OIC_LOG(INFO, TAG, "Exiting SecurePortDiscoveryHandler.");
}
{
OIC_LOG(INFO, TAG, "Skiping Null response");
}
+
return OC_STACK_DELETE_TRANSACTION;
}
-/**
- * Callback handler for PMDeviceDiscovery API.
- *
- * @param[in] ctx User context
- * @param[in] handle Handler for response
- * @param[in] clientResponse Response information (It will contain payload)
- * @return OC_STACK_KEEP_TRANSACTION to keep transaction and
- * OC_STACK_DELETE_TRANSACTION to delete it.
- */
static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
OCClientResponse *clientResponse)
{
OIC_LOG(INFO, TAG, "Unknown payload type");
return OC_STACK_KEEP_TRANSACTION;
}
- OicSecDoxm_t *ptrDoxm = JSONToDoxmBin(
- ((OCSecurityPayload*)clientResponse->payload)->securityData);
- if (NULL == ptrDoxm)
+
+ OicSecDoxm_t *ptrDoxm = NULL;
+ uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
+ size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
+
+ OCStackResult res = CBORPayloadToDoxm(payload, size, &ptrDoxm);
+ if ((NULL == ptrDoxm) || (OC_STACK_OK != res))
{
- OIC_LOG(INFO, TAG, "Ignoring malformed JSON");
+ OIC_LOG(INFO, TAG, "Ignoring malformed CBOR");
return OC_STACK_KEEP_TRANSACTION;
}
else
{
- OIC_LOG(DEBUG, TAG, "Successfully converted doxm json to bin.");
+ OIC_LOG(DEBUG, TAG, "Successfully converted doxm cbor to bin.");
//If this is owend device discovery we have to filter out the responses.
DiscoveryInfo* pDInfo = (DiscoveryInfo*)ctx;
DeleteDoxmBinData(ptrDoxm);
return OC_STACK_KEEP_TRANSACTION;
}
- char rsrc_uri[MAX_URI_LENGTH+1] = {0};
- int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",
- OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM);
- if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))
- {
- OIC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");
- return OC_STACK_ERROR;
- }
- //Try to the unicast discovery to getting secure port
- char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};
- if(!PMGenerateQuery(false,
- clientResponse->devAddr.addr, clientResponse->devAddr.port,
- clientResponse->connType,
- query, sizeof(query), rsrc_uri))
- {
- OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
- return OC_STACK_KEEP_TRANSACTION;
- }
- OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
-
- OCCallbackData cbData;
- cbData.cb = &SecurePortDiscoveryHandler;
- cbData.context = ctx;
- cbData.cd = NULL;
- OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,
- clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);
- // TODO: Should we use the default secure port in case of error?
- if(OC_STACK_OK != ret)
+
+ res = SecurePortDiscovery(pDInfo, clientResponse);
+ if(OC_STACK_OK != res)
{
- OIC_LOG(ERROR, TAG, "Failed to Secure Port Discovery");
+ OIC_LOG(ERROR, TAG, "Failed to SecurePortDiscovery");
+ DeleteDoxmBinData(ptrDoxm);
return OC_STACK_KEEP_TRANSACTION;
}
- else
- {
- OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);
- }
+
OIC_LOG(INFO, TAG, "Exiting ProvisionDiscoveryHandler.");
}
return res;
}
+static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse)
+{
+ OIC_LOG(DEBUG, TAG, "IN SecurePortDiscovery");
+
+ if(NULL == discoveryInfo || NULL == clientResponse)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ char rsrc_uri[MAX_URI_LENGTH+1] = {0};
+ int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",
+ OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM);
+ if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))
+ {
+ OIC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");
+ return OC_STACK_ERROR;
+ }
+ //Try to the unicast discovery to getting secure port
+ char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};
+ if(!PMGenerateQuery(false,
+ clientResponse->devAddr.addr, clientResponse->devAddr.port,
+ clientResponse->connType,
+ query, sizeof(query), rsrc_uri))
+ {
+ OIC_LOG(ERROR, TAG, "SecurePortDiscovery : Failed to generate query");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+ OCCallbackData cbData;
+ cbData.cb = &SecurePortDiscoveryHandler;
+ cbData.context = (void*)discoveryInfo;
+ cbData.cd = NULL;
+ OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,
+ clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to Secure Port Discovery");
+ return ret;
+ }
+ else
+ {
+ OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT SecurePortDiscovery");
+
+ return ret;
+}
+
+static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
+ const OCClientResponse *clientResponse)
+{
+ OIC_LOG(DEBUG, TAG, "IN SecurityVersionDiscovery");
+
+ if(NULL == discoveryInfo || NULL == clientResponse)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ //Try to the unicast discovery to getting security version
+ char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};
+ if(!PMGenerateQuery(false,
+ clientResponse->devAddr.addr, clientResponse->devAddr.port,
+ clientResponse->connType,
+ query, sizeof(query), OIC_RSRC_VER_URI))
+ {
+ OIC_LOG(ERROR, TAG, "SecurityVersionDiscovery : Failed to generate query");
+ return OC_STACK_ERROR;
+ }
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+ OCCallbackData cbData;
+ cbData.cb = &SecurityVersionDiscoveryHandler;
+ cbData.context = (void*)discoveryInfo;
+ cbData.cd = NULL;
+ OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,
+ clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to Security Version Discovery");
+ return ret;
+ }
+ else
+ {
+ OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT SecurityVersionDiscovery");
+
+ return ret;
+}
+
/**
* Function to print OCProvisionDev_t for debug purpose.
*
OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
{
CHECK_PDM_INIT(TAG);
- if (NULL != *UUIDLIST)
+ if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
{
- OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
return OC_STACK_INVALID_PARAM;
}
- if (NULL == UUID)
+ if (NULL != *UUIDLIST )
{
+ OIC_LOG(ERROR, TAG, "Not null list will cause memory leak");
return OC_STACK_INVALID_PARAM;
}
bool result = false;
#include "provisioningdatabasemanager.h"
#include "base64.h"
#include "utlist.h"
+#include "ocpayload.h"
#ifdef __WITH_X509__
#include "crlresource.h"
OCClientResponseHandler responseHandler)
{
OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
- if(!secPayload)
+ if (!secPayload)
{
OIC_LOG(ERROR, TAG, "Failed to memory allocation");
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToCredJSON(cred);
- if(NULL == secPayload->securityData)
+ OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData, &secPayload->payloadSize);
+ if((OC_STACK_OK != res) && (NULL == secPayload->securityData))
{
- OICFree(secPayload);
- OIC_LOG(ERROR, TAG, "Failed to BinToCredJSON");
+ OCPayloadDestroy((OCPayload *)secPayload);
+ OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
return OC_STACK_NO_MEMORY;
}
- OIC_LOG_V(INFO, TAG, "Credential for provisioning : %s",secPayload->securityData);
+ OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
+ OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
if(!PMGenerateQuery(true,
deviceInfo->endpoint.addr,
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToCrlJSON(crl);
- if (NULL == secPayload->securityData)
+ OCStackResult res = CrlToCBORPayload(crl, &secPayload->securityData, &secPayload->payloadSize);
+ if((OC_STACK_OK != res) && (NULL == secPayload->securityData))
{
OICFree(secPayload);
OIC_LOG(ERROR, TAG, "Failed to BinToCrlJSON");
return OC_STACK_NO_MEMORY;
}
- OIC_LOG_V(INFO, TAG, "CRL : %s", secPayload->securityData);
+ OIC_LOG(DEBUG, TAG, "Created payload for CRL:");
+ OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
if(!PMGenerateQuery(true,
query, sizeof(query), OIC_RSRC_CRL_URI))
{
OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
- OICFree(secPayload->securityData);
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
CRLData_t *crlData = (CRLData_t *) OICCalloc(1, sizeof(CRLData_t));
if (crlData == NULL)
{
- OICFree(secPayload->securityData);
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
crlData->resArr = (OCProvisionResult_t*)OICCalloc(1, sizeof(OCProvisionResult_t));
if (crlData->resArr == NULL)
{
- OICFree(secPayload->securityData);
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToCredJSON(cred);
+ OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData,
+ &secPayload->payloadSize);
- if (NULL == secPayload->securityData)
+ if ((OC_STACK_OK != res) || (NULL == secPayload->securityData))
{
OICFree(secPayload);
- OIC_LOG(ERROR, TAG, "Failed to BinToCredJSON");
+ OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
return OC_STACK_NO_MEMORY;
}
- OIC_LOG_V(INFO, TAG, "Credential for provisioning : %s",secPayload->securityData);
+ OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
+ OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
if(!PMGenerateQuery(true,
deviceInfo->endpoint.addr,
query, sizeof(query), OIC_RSRC_CRED_URI))
{
OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
- OICFree(secPayload->securityData);
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
{
VERIFY_NON_NULL(TAG, pDev2, ERROR, OC_STACK_INVALID_PARAM);
}
- VERIFY_NON_NULL(TAG, resultCallback, ERROR, OC_STACK_INVALID_CALLBACK);
+ if (!resultCallback)
+ {
+ OIC_LOG(INFO, TAG, "SRPUnlinkDevices : NULL Callback");
+ return OC_STACK_INVALID_CALLBACK;
+ }
+ if (SYMMETRIC_PAIR_WISE_KEY == type &&
+ 0 == memcmp(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, sizeof(OicUuid_t)))
+ {
+ OIC_LOG(INFO, TAG, "SRPUnlinkDevices : Same device ID");
+ return OC_STACK_INVALID_PARAM;
+ }
if (SYMMETRIC_PAIR_WISE_KEY == type &&
!(OWNER_PSK_LENGTH_128 == keySize || OWNER_PSK_LENGTH_256 == keySize))
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToAclJSON(acl);
- if(NULL == secPayload->securityData)
+ if(OC_STACK_OK != AclToCBORPayload(acl, &secPayload->securityData, &secPayload->payloadSize))
{
- OICFree(secPayload);
- OIC_LOG(ERROR, TAG, "Failed to BinToAclJSON");
+ OCPayloadDestroy((OCPayload *)secPayload);
+ OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
return OC_STACK_NO_MEMORY;
}
- OIC_LOG_V(INFO, TAG, "ACL : %s", secPayload->securityData);
-
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
if(!PMGenerateQuery(true,
selectedDeviceInfo->endpoint.addr,
ACLData_t *aclData = (ACLData_t *) OICCalloc(1, sizeof(ACLData_t));
if (aclData == NULL)
{
- OICFree(secPayload->securityData);
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
if (aclData->resArr == NULL)
{
OICFree(aclData);
- OICFree(secPayload->securityData);
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload *)secPayload);
OIC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
static void registerResultForDirectPairingProvisioning(PconfData_t *pconfData,
OCStackResult stackresult)
{
- OIC_LOG_V(INFO, TAG, "Inside registerResultForDirectPairingProvisioning pconfData->numOfResults is %d\n",
- pconfData->numOfResults);
+ OIC_LOG_V(INFO, TAG, "Inside registerResultForDirectPairingProvisioning "
+ "pconfData->numOfResults is %d\n", pconfData->numOfResults);
memcpy(pconfData->resArr[(pconfData->numOfResults)].deviceId.id,
pconfData->deviceInfo->doxm->deviceID.id, UUID_LENGTH);
pconfData->resArr[(pconfData->numOfResults)].res = stackresult;
{
if(OC_STACK_RESOURCE_CREATED == clientResponse->result)
{
- registerResultForDirectPairingProvisioning(pconfData, OC_STACK_RESOURCE_CREATED);
+ registerResultForDirectPairingProvisioning(pconfData, OC_STACK_OK);
((OCProvisionResultCB)(resultCallback))(pconfData->ctx, pconfData->numOfResults,
pconfData->resArr,
false);
OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
return OC_STACK_ERROR;
}
- memcpy(&pconf->rowner, &provTooldeviceID, sizeof(OicUuid_t));
+ memcpy(&pconf->rownerID, &provTooldeviceID, sizeof(OicUuid_t));
OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
if(!secPayload)
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
- secPayload->securityData = BinToPconfJSON(pconf);
- if(NULL == secPayload->securityData)
+
+ if (OC_STACK_OK != PconfToCBORPayload(pconf, &(secPayload->securityData),
+ &(secPayload->payloadSize)))
{
- OICFree(secPayload);
- OIC_LOG(ERROR, TAG, "Failed to BinToPconfJSON");
+ OCPayloadDestroy((OCPayload*)secPayload);
+ OIC_LOG(ERROR, TAG, "Failed to PconfToCborPayload");
return OC_STACK_NO_MEMORY;
}
- OIC_LOG_V(INFO, TAG, "PCONF : %s", secPayload->securityData);
+ OIC_LOG(DEBUG, TAG, "Created payload for pconf set");
+ OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
if(!PMGenerateQuery(true,
- selectedDeviceInfo->endpoint.addr,
- selectedDeviceInfo->securePort,
- selectedDeviceInfo->connType,
- query, sizeof(query), OIC_RSRC_PCONF_URI))
+ selectedDeviceInfo->endpoint.addr,
+ selectedDeviceInfo->securePort,
+ selectedDeviceInfo->connType,
+ query, sizeof(query), OIC_RSRC_PCONF_URI))
{
OIC_LOG(ERROR, TAG, "SRPProvisionDirectPairing : Failed to generate query");
return OC_STACK_ERROR;
PconfData_t *pconfData = (PconfData_t *) OICCalloc(1, sizeof(PconfData_t));
if (NULL == pconfData)
{
- OICFree(secPayload->securityData);
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload*)secPayload);
OIC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
if (NULL == pconfData->resArr)
{
OICFree(pconfData);
- OICFree(secPayload->securityData);
- OICFree(secPayload);
+ OCPayloadDestroy((OCPayload*)secPayload);
OIC_LOG(ERROR, TAG, "Unable to allocate memory");
return OC_STACK_NO_MEMORY;
}
return OC_STACK_INVALID_PARAM;
}
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(revokedDev->doxm->deviceID.id)) + 1] = {};
- uint32_t base64Len = 0;
- if (B64_OK != b64Encode(revokedDev->doxm->deviceID.id, sizeof(revokedDev->doxm->deviceID.id),
- base64Buff, sizeof(base64Buff), &base64Len))
+ char *subID = NULL;
+ OCStackResult ret = ConvertUuidToStr(&revokedDev->doxm->deviceID, &subID);
+ if(OC_STACK_OK != ret)
{
- OIC_LOG(ERROR, TAG, "SendDeleteCredentialRequest : Failed to base64 encoding");
+ OIC_LOG(ERROR, TAG, "SendDeleteCredentialRequest : Failed to canonical UUID encoding");
return OC_STACK_ERROR;
}
char reqBuf[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
int snRet = 0;
- //coaps://0.0.0.0:5684/oic/sec/cred?sub=(BASE64 ENCODED UUID)
+ //coaps://0.0.0.0:5684/oic/sec/cred?subjectid=(Canonical ENCODED UUID)
snRet = snprintf(reqBuf, sizeof(reqBuf), SRP_FORM_DELETE_CREDENTIAL, destDev->endpoint.addr,
- destDev->securePort, OIC_RSRC_CRED_URI, OIC_JSON_SUBJECT_NAME, base64Buff);
+ destDev->securePort, OIC_RSRC_CRED_URI, OIC_JSON_SUBJECTID_NAME, subID);
+ OICFree(subID);
if (snRet < 0)
{
OIC_LOG_V(ERROR, TAG, "SendDeleteCredentialRequest : Error (snprintf) %d\n", snRet);
OIC_LOG(DEBUG, TAG, "Sending remove credential request to resource server");
- OCStackResult ret = OCDoResource(NULL, OC_REST_DELETE, reqBuf,
+ ret = OCDoResource(NULL, OC_REST_DELETE, reqBuf,
&destDev->endpoint, NULL,
CT_ADAPTER_IP, OC_HIGH_QOS, &cbData, NULL, 0);
if (OC_STACK_OK != ret)
{
OIC_LOG(INFO, TAG, "IN SRPUnlinkDevices");
- if (!pTargetDev1 || !pTargetDev2 || !resultCallback)
+ if (!pTargetDev1 || !pTargetDev2 || !pTargetDev1->doxm || !pTargetDev2->doxm)
{
OIC_LOG(INFO, TAG, "SRPUnlinkDevices : NULL parameters");
return OC_STACK_INVALID_PARAM;
}
+ if (!resultCallback)
+ {
+ OIC_LOG(INFO, TAG, "SRPUnlinkDevices : NULL Callback");
+ return OC_STACK_INVALID_CALLBACK;
+ }
+ if (0 == memcmp(&pTargetDev1->doxm->deviceID, &pTargetDev2->doxm->deviceID, sizeof(OicUuid_t)))
+ {
+ OIC_LOG(INFO, TAG, "SRPUnlinkDevices : Same device ID");
+ return OC_STACK_INVALID_PARAM;
+ }
+
OIC_LOG(INFO, TAG, "Unlinking following devices: ");
PMPrintOCProvisionDev(pTargetDev1);
PMPrintOCProvisionDev(pTargetDev2);
OCStackResult res = OC_STACK_ERROR;
RemoveData_t* removeData = (RemoveData_t*)delDevCtx;
- if(removeData)
+
+ if (clientResponse)
{
- if (clientResponse)
+ OicUuid_t revDevUuid = {.id={0}};
+ if(UUID_LENGTH == clientResponse->identity.id_length)
{
- OicUuid_t revDevUuid = {.id={0}};
- if(UUID_LENGTH == clientResponse->identity.id_length)
+ memcpy(revDevUuid.id, clientResponse->identity.id, sizeof(revDevUuid.id));
+ if (OC_STACK_RESOURCE_DELETED == clientResponse->result)
{
- memcpy(revDevUuid.id, clientResponse->identity.id, sizeof(revDevUuid.id));
- if (OC_STACK_RESOURCE_DELETED == clientResponse->result)
+ res = PDMUnlinkDevices(&removeData->revokeTargetDev->doxm->deviceID, &revDevUuid);
+ if (OC_STACK_OK != res)
{
- res = PDMUnlinkDevices(&removeData->revokeTargetDev->doxm->deviceID, &revDevUuid);
- if (OC_STACK_OK != res)
- {
- OIC_LOG(ERROR, TAG, "PDMSetLinkStale() FAIL: PDB is an obsolete one.");
- registerResultForRemoveDevice(removeData, &revDevUuid,
- OC_STACK_INCONSISTENT_DB, true);
+ OIC_LOG(ERROR, TAG, "PDMSetLinkStale() FAIL: PDB is an obsolete one.");
+ registerResultForRemoveDevice(removeData, &revDevUuid,
+ OC_STACK_INCONSISTENT_DB, true);
- return OC_STACK_DELETE_TRANSACTION;
- }
-
- registerResultForRemoveDevice(removeData, &revDevUuid,
- OC_STACK_RESOURCE_DELETED, false);
- }
- else
- {
- registerResultForRemoveDevice(removeData, &revDevUuid,
- clientResponse->result, true);
- OIC_LOG(ERROR, TAG, "Unexpected result from DELETE credential request!");
+ return OC_STACK_DELETE_TRANSACTION;
}
+
+ registerResultForRemoveDevice(removeData, &revDevUuid,
+ OC_STACK_RESOURCE_DELETED, false);
}
else
{
- OIC_LOG_V(WARNING, TAG, "Incorrect length of device UUID was sent from %s:%d",
- clientResponse->devAddr.addr, clientResponse->devAddr.port);
-
- if (OC_STACK_RESOURCE_DELETED == clientResponse->result)
- {
- /**
- * Since server's credential was deleted,
- * register result as OC_STACK_INCONSISTENT_DB with NULL UUID.
- */
-
- OIC_LOG_V(ERROR, TAG, "But server's credential was deleted.");
- registerResultForRemoveDevice(removeData, NULL, OC_STACK_INCONSISTENT_DB, true);
- }
- else
- {
- registerResultForRemoveDevice(removeData, NULL, clientResponse->result, true);
- }
+ registerResultForRemoveDevice(removeData, &revDevUuid,
+ clientResponse->result, true);
+ OIC_LOG(ERROR, TAG, "Unexpected result from DELETE credential request!");
}
}
else
{
- registerResultForRemoveDevice(removeData, NULL, OC_STACK_ERROR, true);
- OIC_LOG(ERROR, TAG, "SRPRemoveDevices received Null clientResponse");
+ OIC_LOG_V(WARNING, TAG, "Incorrect length of device UUID was sent from %s:%d",
+ clientResponse->devAddr.addr, clientResponse->devAddr.port);
+
+ if (OC_STACK_RESOURCE_DELETED == clientResponse->result)
+ {
+ /**
+ * Since server's credential was deleted,
+ * register result as OC_STACK_INCONSISTENT_DB with NULL UUID.
+ */
+ OIC_LOG_V(ERROR, TAG, "But server's credential was deleted.");
+ registerResultForRemoveDevice(removeData, NULL, OC_STACK_INCONSISTENT_DB, true);
+ }
+ else
+ {
+ registerResultForRemoveDevice(removeData, NULL, clientResponse->result, true);
+ }
}
}
else
{
- OIC_LOG(WARNING, TAG, "SRPRemoveDevices received null context");
+ registerResultForRemoveDevice(removeData, NULL, OC_STACK_ERROR, true);
+ OIC_LOG(ERROR, TAG, "SRPRemoveDevices received Null clientResponse");
}
+
return OC_STACK_DELETE_TRANSACTION;
}
{
OIC_LOG(INFO, TAG, "IN SRPRemoveDevice");
- if (!pTargetDev || !resultCallback || 0 == waitTimeForOwnedDeviceDiscovery)
+ if (!pTargetDev || 0 == waitTimeForOwnedDeviceDiscovery)
{
OIC_LOG(INFO, TAG, "SRPRemoveDevice : NULL parameters");
return OC_STACK_INVALID_PARAM;
}
+ if (!resultCallback)
+ {
+ OIC_LOG(INFO, TAG, "SRPRemoveDevice : NULL Callback");
+ return OC_STACK_INVALID_CALLBACK;
+ }
// Declare variables in here to handle error cases with goto statement.
OCProvisionDev_t* pOwnedDevList = NULL;
sptest_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
sptest_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
sptest_env.PrependUnique(LIBS = [ 'ocpmapi',
+ 'oc',
'ocsrm',
'octbstack',
'oc_logger',
#include "gtest/gtest.h"
#include "ocprovisioningmanager.h"
+static OicSecAcl_t acl1;
+static OicSecAcl_t acl2;
+static OCProvisionDev_t pDev1;
+static OCProvisionDev_t pDev2;
+static OicSecCredType_t credType = SYMMETRIC_PAIR_WISE_KEY;
+static OicSecOxm_t oicSecDoxmJustWorks = OIC_JUST_WORKS;
+static OicSecOxm_t oicSecDoxmRandomPin = OIC_RANDOM_DEVICE_PIN;
+static OicSecDoxm_t defaultDoxm1 =
+{
+ NULL, /* OicUrn_t *oxmType */
+ 0, /* size_t oxmTypeLen */
+ &oicSecDoxmJustWorks, /* uint16_t *oxm */
+ 1, /* size_t oxmLen */
+ OIC_JUST_WORKS, /* uint16_t oxmSel */
+ SYMMETRIC_PAIR_WISE_KEY,/* OicSecCredType_t sct */
+ false, /* bool owned */
+ {{0}}, /* OicUuid_t deviceID */
+ false, /* bool dpc */
+ {{0}}, /* OicUuid_t owner */
+};
+
+static OicSecDoxm_t defaultDoxm2 =
+{
+ NULL, /* OicUrn_t *oxmType */
+ 0, /* size_t oxmTypeLen */
+ &oicSecDoxmRandomPin, /* uint16_t *oxm */
+ 1, /* size_t oxmLen */
+ OIC_RANDOM_DEVICE_PIN, /* uint16_t oxmSel */
+ SYMMETRIC_PAIR_WISE_KEY,/* OicSecCredType_t sct */
+ false, /* bool owned */
+ {{0}}, /* OicUuid_t deviceID */
+ false, /* bool dpc */
+ {{0}}, /* OicUuid_t owner */
+};
+
static void provisioningCB (void* UNUSED1, int UNUSED2, OCProvisionResult_t *UNUSED3, bool UNUSED4)
{
//dummy callback
(void) UNUSED4;
}
+TEST(OCProvisionPairwiseDevicesTest, NullDevice1)
+{
+ pDev1.doxm = &defaultDoxm1;
+ uint8_t deviceId1[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64};
+ memcpy(pDev1.doxm->deviceID.id, deviceId1, sizeof(deviceId1));
+
+ pDev2.doxm = &defaultDoxm2;
+ uint8_t deviceId2[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x63};
+ memcpy(pDev2.doxm->deviceID.id, deviceId2, sizeof(deviceId2));
+
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCProvisionPairwiseDevices(NULL, credType,
+ OWNER_PSK_LENGTH_128, NULL, &acl1,
+ &pDev2, &acl2, &provisioningCB));
+}
+
+TEST(OCProvisionPairwiseDevicesTest, NullDevice2)
+{
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCProvisionPairwiseDevices(NULL, credType,
+ OWNER_PSK_LENGTH_128, &pDev1, &acl1,
+ NULL, &acl2, &provisioningCB));
+}
+
+TEST(OCProvisionPairwiseDevicesTest, SamelDeviceId)
+{
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCProvisionPairwiseDevices(NULL, credType,
+ OWNER_PSK_LENGTH_128, &pDev1, &acl1,
+ &pDev1, &acl2, &provisioningCB));
+}
+
+TEST(OCProvisionPairwiseDevicesTest, NullCallback)
+{
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCProvisionPairwiseDevices(NULL, credType,
+ OWNER_PSK_LENGTH_128, &pDev1, &acl1,
+ &pDev2, &acl2, NULL));
+}
+
+TEST(OCProvisionPairwiseDevicesTest, InvalidKeySize)
+{
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCProvisionPairwiseDevices(NULL, credType,
+ 0, &pDev1, &acl1,
+ &pDev2, &acl2 ,&provisioningCB));
+}
+
TEST(OCUnlinkDevicesTest, NullDevice1)
{
- OCProvisionDev_t dev2;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, OCUnlinkDevices(NULL, NULL, &dev2, provisioningCB));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCUnlinkDevices(NULL, NULL, &pDev2, provisioningCB));
}
TEST(OCUnlinkDevicesTest, NullDevice2)
{
- OCProvisionDev_t dev1;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, OCUnlinkDevices(NULL, &dev1, NULL, provisioningCB));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCUnlinkDevices(NULL, &pDev1, NULL, provisioningCB));
}
TEST(OCUnlinkDevicesTest, NullCallback)
{
- OCProvisionDev_t dev1;
- OCProvisionDev_t dev2;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, OCUnlinkDevices(NULL, &dev1, &dev2, NULL));
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCUnlinkDevices(NULL, &pDev1, &pDev2, NULL));
}
+TEST(OCUnlinkDevicesTest, SamelDeviceId)
+{
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCUnlinkDevices(NULL,&pDev1, &pDev1, &provisioningCB));
+}
+
+
TEST(OCRemoveDeviceTest, NullTargetDevice)
{
unsigned short waitTime = 10 ;
TEST(OCRemoveDeviceTest, NullResultCallback)
{
unsigned short waitTime = 10;
- OCProvisionDev_t dev1;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, OCRemoveDevice(NULL, waitTime, &dev1, NULL));
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCRemoveDevice(NULL, waitTime, &pDev1, NULL));
}
TEST(OCRemoveDeviceTest, ZeroWaitTime)
{
unsigned short waitTime = 0;
- OCProvisionDev_t dev1;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, OCRemoveDevice(NULL, waitTime, &dev1, NULL));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCRemoveDevice(NULL, waitTime, &pDev1, provisioningCB));
}
TEST(OCGetDevInfoFromNetworkTest, NullUnOwnedDeviceInfo)
TEST(OCGetDevInfoFromNetworkTest, ZeroWaitTime)
{
unsigned short waitTime = 0;
- OCProvisionDev_t *ownedList;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, OCGetDevInfoFromNetwork(waitTime, &ownedList, NULL));
+ OCProvisionDev_t *ownedList = NULL;
+ OCProvisionDev_t *unownedList = NULL;
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCGetDevInfoFromNetwork(waitTime, &ownedList, &unownedList));
}
TEST(OCGetLinkedStatusTest, NULLDeviceID)
TEST(JustWorksOxMTest, NullParam)
{
-
OTMContext_t* otmCtx = NULL;
OCStackResult res = OC_STACK_ERROR;
- char* payloadRes;
+ uint8_t *payloadRes = NULL;
+ size_t size = 0;
//LoadSecretJustWorksCallback always returns OC_STACK_OK.
res = LoadSecretJustWorksCallback(otmCtx);
res = CreateSecureSessionJustWorksCallback(otmCtx);
EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- payloadRes = CreateJustWorksSelectOxmPayload(otmCtx);
- EXPECT_TRUE(NULL == payloadRes);
+ res = CreateJustWorksSelectOxmPayload(otmCtx, &payloadRes, &size);
+ EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- payloadRes = CreateJustWorksOwnerTransferPayload(otmCtx);
- EXPECT_TRUE(NULL == payloadRes);
+ res = CreateJustWorksOwnerTransferPayload(otmCtx, &payloadRes, &size);
+ EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
OTMContext_t otmCtx2;
otmCtx2.selectedDeviceInfo = NULL;
res = CreateSecureSessionJustWorksCallback(&otmCtx2);
EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- payloadRes = CreateJustWorksSelectOxmPayload(&otmCtx2);
- EXPECT_TRUE(NULL == payloadRes);
+ res = CreateJustWorksSelectOxmPayload(&otmCtx2, &payloadRes, &size);
+ EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- payloadRes = CreateJustWorksOwnerTransferPayload(&otmCtx2);
- EXPECT_TRUE(NULL == payloadRes);
+ res = CreateJustWorksOwnerTransferPayload(&otmCtx2, &payloadRes, &size);
+ EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
}
TEST(RandomPinOxMTest, NullParam)
{
OTMContext_t* otmCtx = NULL;
OCStackResult res = OC_STACK_ERROR;
- char* payloadRes;
+ uint8_t *payloadRes = NULL;
+ size_t size = 0;
//LoadSecretJustWorksCallback always returns OC_STACK_OK.
res = InputPinCodeCallback(otmCtx);
EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- res = CreateSecureSessionRandomPinCallbak(otmCtx);
+ res = CreateSecureSessionRandomPinCallback(otmCtx);
EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- payloadRes = CreatePinBasedSelectOxmPayload(otmCtx);
- EXPECT_TRUE(NULL == payloadRes);
+ res = CreatePinBasedSelectOxmPayload(otmCtx, &payloadRes, &size);
+ EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- payloadRes = CreatePinBasedOwnerTransferPayload(otmCtx);
- EXPECT_TRUE(NULL == payloadRes);
+ res = CreatePinBasedOwnerTransferPayload(otmCtx, &payloadRes, &size);
+ EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
OTMContext_t otmCtx2;
otmCtx2.selectedDeviceInfo = NULL;
res = InputPinCodeCallback(&otmCtx2);
EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- res = CreateSecureSessionRandomPinCallbak(&otmCtx2);
+ res = CreateSecureSessionRandomPinCallback(&otmCtx2);
EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- payloadRes = CreatePinBasedSelectOxmPayload(&otmCtx2);
- EXPECT_TRUE(NULL == payloadRes);
+ res = CreatePinBasedSelectOxmPayload(&otmCtx2, &payloadRes, &size);
+ EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
- payloadRes = CreatePinBasedOwnerTransferPayload(&otmCtx2);
- EXPECT_TRUE(NULL == payloadRes);
+ res = CreatePinBasedOwnerTransferPayload(&otmCtx2, &payloadRes, &size);
+ EXPECT_TRUE(OC_STACK_INVALID_PARAM == res);
}
#include "gtest/gtest.h"
#include "provisioningdatabasemanager.h"
+#define DB_FILE "PDM.db"
const char ID_1 [] = "1111111111111111";
const char ID_2 [] = "2111111111111111";
const char ID_3 [] = "3111111111111111";
TEST(CallPDMAPIbeforeInit, BeforeInit)
{
+ if (0 == access(DB_FILE, F_OK))
+ {
+ EXPECT_EQ(0, unlink(DB_FILE));
+ }
EXPECT_EQ(OC_STACK_PDM_IS_NOT_INITIALIZED, PDMAddDevice(NULL));
EXPECT_EQ(OC_STACK_PDM_IS_NOT_INITIALIZED, PDMIsDuplicateDevice(NULL,NULL));
EXPECT_EQ(OC_STACK_PDM_IS_NOT_INITIALIZED, PDMLinkDevices(NULL, NULL));
EXPECT_TRUE(0 == memcmp(ptr->dev.id, uid2.id,sizeof(uid2.id)));
ptr = ptr->next;
}
-}
\ No newline at end of file
+}
static OicSecCredType_t credType = SYMMETRIC_PAIR_WISE_KEY;
static OCProvisionDev_t selectedDeviceInfo;
static OicSecPconf_t pconf;
+static OicSecOxm_t oicSecDoxmJustWorks = OIC_JUST_WORKS;
+static OicSecOxm_t oicSecDoxmRandomPin = OIC_RANDOM_DEVICE_PIN;
+static OicSecDoxm_t defaultDoxm1 =
+{
+ NULL, /* OicUrn_t *oxmType */
+ 0, /* size_t oxmTypeLen */
+ &oicSecDoxmJustWorks, /* uint16_t *oxm */
+ 1, /* size_t oxmLen */
+ OIC_JUST_WORKS, /* uint16_t oxmSel */
+ SYMMETRIC_PAIR_WISE_KEY,/* OicSecCredType_t sct */
+ false, /* bool owned */
+ {{0}}, /* OicUuid_t deviceID */
+ false, /* bool dpc */
+ {{0}}, /* OicUuid_t owner */
+};
+
+static OicSecDoxm_t defaultDoxm2 =
+{
+ NULL, /* OicUrn_t *oxmType */
+ 0, /* size_t oxmTypeLen */
+ &oicSecDoxmRandomPin, /* uint16_t *oxm */
+ 1, /* size_t oxmLen */
+ OIC_RANDOM_DEVICE_PIN, /* uint16_t oxmSel */
+ SYMMETRIC_PAIR_WISE_KEY,/* OicSecCredType_t sct */
+ false, /* bool owned */
+ {{0}}, /* OicUuid_t deviceID */
+ false, /* bool dpc */
+ {{0}}, /* OicUuid_t owner */
+};
static void provisioningCB (void* UNUSED1, int UNUSED2, OCProvisionResult_t *UNUSED3, bool UNUSED4)
{
TEST(SRPProvisionACLTest, NullDeviceInfo)
{
+ pDev1.doxm = &defaultDoxm1;
+ uint8_t deviceId1[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64};
+ memcpy(pDev1.doxm->deviceID.id, deviceId1, sizeof(deviceId1));
+
+ pDev2.doxm = &defaultDoxm2;
+ uint8_t deviceId2[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x63};
+ memcpy(pDev2.doxm->deviceID.id, deviceId2, sizeof(deviceId2));
+
EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPProvisionACL(NULL, NULL, &acl, &provisioningCB));
}
&pDev2, &provisioningCB));
}
+TEST(SRPProvisionCredentialsTest, SamelDeviceId)
+{
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPProvisionCredentials(NULL, credType,
+ OWNER_PSK_LENGTH_128, &pDev1,
+ &pDev1, &provisioningCB));
+}
+
TEST(SRPProvisionCredentialsTest, NullCallback)
{
EXPECT_EQ(OC_STACK_INVALID_CALLBACK, SRPProvisionCredentials(NULL, credType,
TEST(SRPUnlinkDevicesTest, NullDevice1)
{
- OCProvisionDev_t dev2;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPUnlinkDevices(NULL, NULL, &dev2, provisioningCB));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPUnlinkDevices(NULL, NULL, &pDev2, provisioningCB));
}
TEST(SRPUnlinkDevicesTest, NullDevice2)
{
- OCProvisionDev_t dev1;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPUnlinkDevices(NULL, &dev1, NULL, provisioningCB));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPUnlinkDevices(NULL, &pDev1, NULL, provisioningCB));
+}
+
+TEST(SRPUnlinkDevicesTest, SamelDeviceId)
+{
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPUnlinkDevices(NULL, &pDev1, &pDev1, provisioningCB));
}
TEST(SRPUnlinkDevicesTest, NullCallback)
{
- OCProvisionDev_t dev1;
- OCProvisionDev_t dev2;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPUnlinkDevices(NULL, &dev1, &dev2, NULL));
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, SRPUnlinkDevices(NULL, &pDev1, &pDev2, NULL));
}
TEST(SRPRemoveDeviceTest, NullTargetDevice)
{
unsigned short waitTime = 10;
OCProvisionDev_t dev1;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, SRPRemoveDevice(NULL, waitTime, &dev1, NULL));
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, SRPRemoveDevice(NULL, waitTime, &dev1, NULL));
}
TEST(SRPRemoveDeviceTest, ZeroWaitTime)
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <stdlib.h>
+#ifdef WITH_ARDUINO
#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdlib.h>
+
#include "ocstack.h"
-#include "logger.h"
+#include "ocserverrequest.h"
#include "oic_malloc.h"
#include "oic_string.h"
-#include "cJSON.h"
-#include "base64.h"
-#include "resourcemanager.h"
-#include "aclresource.h"
-#include "psinterface.h"
+#include "ocrandom.h"
+#include "ocpayload.h"
#include "utlist.h"
+#include "payload_logging.h"
#include "srmresourcestrings.h"
+#include "aclresource.h"
#include "doxmresource.h"
+#include "resourcemanager.h"
#include "srmutility.h"
-#include "ocserverrequest.h"
-#include <stdlib.h>
-#ifdef WITH_ARDUINO
-#include <string.h>
-#else
-#include <strings.h>
-#endif
+#include "psinterface.h"
+
+#include "security_internals.h"
#define TAG "SRM-ACL"
#define NUMBER_OF_SEC_PROV_RSCS 4
#define NUMBER_OF_DEFAULT_SEC_RSCS 2
-OicSecAcl_t *gAcl = NULL;
-static OCResourceHandle gAclHandle = NULL;
+static const uint8_t ACL_MAP_SIZE = 2;
+static const uint8_t ACL_ACLIST_MAP_SIZE = 1;
+static const uint8_t ACL_ACES_MAP_SIZE = 3;
+static const uint8_t ACL_RESOURCE_MAP_SIZE = 4;
+
+
+// CborSize is the default cbor payload size being used.
+static const uint16_t CBOR_SIZE = 2048;
+
+static OicSecAcl_t *gAcl = NULL;
+static OCResourceHandle gAclHandle = NULL;
/**
* This function frees OicSecAcl_t object's fields and object itself.
static void FreeACE(OicSecAcl_t *ace)
{
size_t i;
- if(NULL == ace)
+ if (NULL == ace)
{
- OIC_LOG (ERROR, TAG, "Invalid Parameter");
+ OIC_LOG(ERROR, TAG, "Invalid Parameter");
return;
}
OICFree(ace->resources);
//Clean Period
- if(ace->periods)
+ if (ace->periods)
{
- for(i = 0; i < ace->prdRecrLen; i++)
+ for (i = 0; i < ace->prdRecrLen; i++)
{
OICFree(ace->periods[i]);
}
}
//Clean Recurrence
- if(ace->recurrences)
+ if (ace->recurrences)
{
- for(i = 0; i < ace->prdRecrLen; i++)
+ for (i = 0; i < ace->prdRecrLen; i++)
{
OICFree(ace->recurrences[i]);
}
OICFree(ace->recurrences);
}
- // Clean Owners
- OICFree(ace->owners);
-
// Clean ACL node itself
OICFree(ace);
}
}
}
-/*
- * This internal method converts ACL data into JSON format.
- *
- * Note: Caller needs to invoke 'free' when finished done using
- * return string.
- */
-char * BinToAclJSON(const OicSecAcl_t * acl)
+static size_t OicSecAclSize(const OicSecAcl_t *secAcl)
+{
+ if (!secAcl)
+ {
+ return 0;
+ }
+ OicSecAcl_t *acl = (OicSecAcl_t *)secAcl;
+ size_t size = 0;
+ while (acl)
+ {
+ size++;
+ acl = acl->next;
+ }
+ return size;
+}
+
+OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, size_t *size)
{
- cJSON *jsonRoot = NULL;
- char *jsonStr = NULL;
+ if (NULL == secAcl || NULL == payload || NULL != *payload || NULL == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
- if (acl)
+ OCStackResult ret = OC_STACK_ERROR;
+ CborError cborEncoderResult = CborNoError;
+ OicSecAcl_t *acl = (OicSecAcl_t *)secAcl;
+ CborEncoder encoder;
+ CborEncoder aclMap;
+ CborEncoder aclListMap;
+ CborEncoder acesArray;
+ uint8_t *outPayload = NULL;
+ size_t cborLen = *size;
+ *size = 0;
+ *payload = NULL;
+
+ if (cborLen == 0)
+ {
+ cborLen = CBOR_SIZE;
+ }
+
+ outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+ // Create ACL Map (aclist, rownerid)
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &aclMap, ACL_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACL Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ACLIST_NAME,
+ strlen(OIC_JSON_ACLIST_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding aclist Name Tag.");
+
+ // Create ACLIST Map (aces)
+ cborEncoderResult = cbor_encoder_create_map(&aclMap, &aclListMap, ACL_ACLIST_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACLIST Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&aclListMap, OIC_JSON_ACES_NAME,
+ strlen(OIC_JSON_ACES_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACES Name Tag.");
+
+ // Create ACES Array
+ cborEncoderResult = cbor_encoder_create_array(&aclListMap, &acesArray, OicSecAclSize(secAcl));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Array.");
+
+ while (acl)
{
- jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ CborEncoder oicSecAclMap;
+ // ACL Map size - Number of mandatory items
+ uint8_t aclMapSize = ACL_ACES_MAP_SIZE;
+ size_t inLen = 0;
+
+ // Create ACL Map
+ if (acl->periods)
+ {
+ ++aclMapSize;
+ }
+ if (acl->recurrences)
+ {
+ ++aclMapSize;
+ }
- cJSON *jsonAclArray = NULL;
- cJSON_AddItemToObject (jsonRoot, OIC_JSON_ACL_NAME, jsonAclArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
+ cborEncoderResult = cbor_encoder_create_map(&acesArray, &oicSecAclMap, aclMapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Map");
+
+ // Subject -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_SUBJECTID_NAME,
+ strlen(OIC_JSON_SUBJECTID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Name Tag.");
+ inLen = (memcmp(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
+ WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
+ if(inLen == WILDCARD_SUBJECT_ID_LEN)
+ {
+ cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, WILDCARD_RESOURCE_URI,
+ strlen(WILDCARD_RESOURCE_URI));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id wildcard Value.");
+ }
+ else
+ {
+ char *subject = NULL;
+ ret = ConvertUuidToStr(&acl->subject, &subject);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, subject, strlen(subject));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
+ OICFree(subject);
+ }
- while(acl)
+ // Resources
{
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
- uint32_t outLen = 0;
- size_t inLen = 0;
- B64Result b64Ret = B64_OK;
+ CborEncoder resources;
+ cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_RESOURCES_NAME,
+ strlen(OIC_JSON_RESOURCES_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Tag.");
- cJSON *jsonAcl = cJSON_CreateObject();
+ cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &resources, acl->resourcesLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Resource Name Array.");
- // Subject -- Mandatory
- outLen = 0;
- if (memcmp(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0)
- {
- inLen = WILDCARD_SUBJECT_ID_LEN;
- }
- else
- {
- inLen = sizeof(OicUuid_t);
- }
- b64Ret = b64Encode(acl->subject.id, inLen, base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonAcl, OIC_JSON_SUBJECT_NAME, base64Buff );
-
- // Resources -- Mandatory
- cJSON *jsonRsrcArray = NULL;
- cJSON_AddItemToObject (jsonAcl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
for (size_t i = 0; i < acl->resourcesLen; i++)
{
- cJSON_AddItemToArray (jsonRsrcArray, cJSON_CreateString(acl->resources[i]));
+
+ CborEncoder rMap;
+ cborEncoderResult = cbor_encoder_create_map(&resources, &rMap, ACL_RESOURCE_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
+ strlen(OIC_JSON_HREF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
+ cborEncoderResult = cbor_encode_text_string(&rMap, acl->resources[i],
+ strlen(acl->resources[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
+ strlen(OIC_JSON_REL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
+
+ // TODO : Need to assign real value of REL
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
+ strlen(OIC_JSON_EMPTY_STRING));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
+ strlen(OIC_JSON_RT_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
+
+ // TODO : Need to assign real value of RT
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
+ strlen(OIC_JSON_EMPTY_STRING));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
+ strlen(OIC_JSON_IF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
+
+ // TODO : Need to assign real value of IF
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
+ strlen(OIC_JSON_EMPTY_STRING));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
+
+
+ cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
+
}
+ cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Name Array.");
+ }
- // Permissions -- Mandatory
- cJSON_AddNumberToObject (jsonAcl, OIC_JSON_PERMISSION_NAME, acl->permission);
- //Period & Recurrence -- Not Mandatory
- if(0 != acl->prdRecrLen)
+ // Permissions -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_PERMISSION_NAME,
+ strlen(OIC_JSON_PERMISSION_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Tag.");
+ cborEncoderResult = cbor_encode_int(&oicSecAclMap, acl->permission);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Permission Name Value.");
+
+ // Period -- Not Mandatory
+ if (acl->periods)
+ {
+
+ CborEncoder period;
+ cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_PERIOD_NAME,
+ strlen(OIC_JSON_PERIOD_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &period, acl->prdRecrLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Array.");
+ for (size_t i = 0; i < acl->prdRecrLen; i++)
{
- cJSON *jsonPeriodArray = NULL;
- cJSON_AddItemToObject (jsonAcl, OIC_JSON_PERIODS_NAME,
- jsonPeriodArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonPeriodArray, ERROR);
- for (size_t i = 0; i < acl->prdRecrLen; i++)
- {
- cJSON_AddItemToArray (jsonPeriodArray,
- cJSON_CreateString(acl->periods[i]));
- }
+ cborEncoderResult = cbor_encode_text_string(&period, acl->periods[i],
+ strlen(acl->periods[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Value in Array.");
}
+ cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &period);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Period Array.");
+ }
- //Recurrence -- Not Mandatory
- if(0 != acl->prdRecrLen && acl->recurrences)
+ // Recurrence -- Not Mandatory
+ if (acl->recurrences)
+ {
+ CborEncoder recurrences;
+ cborEncoderResult = cbor_encode_text_string(&oicSecAclMap, OIC_JSON_RECURRENCES_NAME,
+ strlen(OIC_JSON_RECURRENCES_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&oicSecAclMap, &recurrences, acl->prdRecrLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array.");
+
+ for (size_t i = 0; i < acl->prdRecrLen; i++)
{
- cJSON *jsonRecurArray = NULL;
- cJSON_AddItemToObject (jsonAcl, OIC_JSON_RECURRENCES_NAME,
- jsonRecurArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonRecurArray, ERROR);
- for (size_t i = 0; i < acl->prdRecrLen; i++)
- {
- cJSON_AddItemToArray (jsonRecurArray,
- cJSON_CreateString(acl->recurrences[i]));
- }
+ cborEncoderResult = cbor_encode_text_string(&recurrences, acl->recurrences[i],
+ strlen(acl->recurrences[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Recurrence Array Value.");
}
+ cborEncoderResult = cbor_encoder_close_container(&oicSecAclMap, &recurrences);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Recurrence Array");
- // Owners -- Mandatory
- cJSON *jsonOwnrArray = NULL;
- cJSON_AddItemToObject (jsonAcl, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
- for (size_t i = 0; i < acl->ownersLen; i++)
- {
- outLen = 0;
+ }
- b64Ret = b64Encode(acl->owners[i].id, sizeof(((OicUuid_t*)0)->id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddItemToArray (jsonOwnrArray, cJSON_CreateString(base64Buff));
- }
+ cborEncoderResult = cbor_encoder_close_container(&acesArray, &oicSecAclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Map.");
+ acl = acl->next;
+ }
- // Attach current acl node to Acl Array
- cJSON_AddItemToArray(jsonAclArray, jsonAcl);
- acl = acl->next;
- }
+ // Close ACES Array
+ cborEncoderResult = cbor_encoder_close_container(&aclListMap, &acesArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Array.");
- jsonStr = cJSON_PrintUnformatted(jsonRoot);
+ // Close ACLIST Map
+ cborEncoderResult = cbor_encoder_close_container(&aclMap, &aclListMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACLIST Map.");
+
+ // Rownerid
+ {
+ char *rowner = NULL;
+ cborEncoderResult = cbor_encode_text_string(&aclMap, OIC_JSON_ROWNERID_NAME,
+ strlen(OIC_JSON_ROWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
+ ret = ConvertUuidToStr(&secAcl->rownerID, &rowner);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&aclMap, rowner, strlen(rowner));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
+ OICFree(rowner);
}
+ // Close ACL Map
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &aclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACL Map.");
+
+ if (CborNoError == cborEncoderResult)
+ {
+ OIC_LOG(DEBUG, TAG, "AclToCBORPayload Successed");
+ *size = encoder.ptr - outPayload;
+ *payload = outPayload;
+ ret = OC_STACK_OK;
+ }
exit:
- if (jsonRoot)
+ if (CborErrorOutOfMemory == cborEncoderResult)
{
- cJSON_Delete(jsonRoot);
+ OIC_LOG(DEBUG, TAG, "AclToCBORPayload:CborErrorOutOfMemory : retry with more memory");
+
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = AclToCBORPayload(secAcl, payload, &cborLen);
+ *size = cborLen;
}
- return jsonStr;
+ else if (cborEncoderResult != CborNoError)
+ {
+ OIC_LOG(ERROR, TAG, "Failed to AclToCBORPayload");
+ OICFree(outPayload);
+ outPayload = NULL;
+ *size = 0;
+ *payload = NULL;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
}
-/*
- * This internal method converts JSON ACL into binary ACL.
- */
-OicSecAcl_t * JSONToAclBin(const char * jsonStr)
+// This function converts CBOR format to ACL data.
+// Caller needs to invoke 'free' when done using
+// note: This function is used in unit test hence not declared static,
+OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
{
+ if (NULL == cborPayload || 0 == size)
+ {
+ return NULL;
+ }
OCStackResult ret = OC_STACK_ERROR;
- OicSecAcl_t * headAcl = NULL;
- OicSecAcl_t * prevAcl = NULL;
- cJSON *jsonRoot = NULL;
- cJSON *jsonAclArray = NULL;
-
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+ CborValue aclCbor = { .parser = NULL };
+ CborParser parser = { .end = NULL };
+ CborError cborFindResult = CborNoError;
+ cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
- jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ OicSecAcl_t *headAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
- jsonAclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME);
- VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
+ // Enter ACL Map
+ CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+ cborFindResult = cbor_value_enter_container(&aclCbor, &aclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
- if (cJSON_Array == jsonAclArray->type)
+ while (cbor_value_is_valid(&aclMap))
{
- int numAcl = cJSON_GetArraySize(jsonAclArray);
- int idx = 0;
-
- VERIFY_SUCCESS(TAG, numAcl > 0, INFO);
- do
+ char* tagName = NULL;
+ size_t len = 0;
+ CborType type = cbor_value_get_type(&aclMap);
+ if (type == CborTextStringType)
{
- cJSON *jsonAcl = cJSON_GetArrayItem(jsonAclArray, idx);
- VERIFY_NON_NULL(TAG, jsonAcl, ERROR);
-
- OicSecAcl_t *acl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
- VERIFY_NON_NULL(TAG, acl, ERROR);
-
- headAcl = (headAcl) ? headAcl : acl;
- if (prevAcl)
+ cborFindResult = cbor_value_dup_text_string(&aclMap, &tagName, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
+ cborFindResult = cbor_value_advance(&aclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
+ }
+ if(tagName)
+ {
+ if (strcmp(tagName, OIC_JSON_ACLIST_NAME) == 0)
{
- prevAcl->next = acl;
- }
+ // Enter ACLIST Map
+ CborValue aclistMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+ cborFindResult = cbor_value_enter_container(&aclMap, &aclistMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACLIST Map.");
- size_t jsonObjLen = 0;
- cJSON *jsonObj = NULL;
-
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
-
- // Subject -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_SUBJECT_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- outLen = 0;
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(acl->subject.id)), ERROR);
- memcpy(acl->subject.id, base64Buff, outLen);
-
- // Resources -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_RESOURCES_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
-
- acl->resourcesLen = (size_t)cJSON_GetArraySize(jsonObj);
- VERIFY_SUCCESS(TAG, acl->resourcesLen > 0, ERROR);
- acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
- VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
-
- size_t idxx = 0;
- do
- {
- cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
- VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
-
- jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
- acl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, (acl->resources[idxx]), ERROR);
- OICStrcpy(acl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
- } while ( ++idxx < acl->resourcesLen);
-
- // Permissions -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonAcl,
- OIC_JSON_PERMISSION_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- acl->permission = jsonObj->valueint;
-
- //Period -- Not Mandatory
- cJSON *jsonPeriodObj = cJSON_GetObjectItem(jsonAcl,
- OIC_JSON_PERIODS_NAME);
- if(jsonPeriodObj)
- {
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonPeriodObj->type,
- ERROR);
- acl->prdRecrLen = (size_t)cJSON_GetArraySize(jsonPeriodObj);
- if(acl->prdRecrLen > 0)
- {
- acl->periods = (char**)OICCalloc(acl->prdRecrLen,
- sizeof(char*));
- VERIFY_NON_NULL(TAG, acl->periods, ERROR);
- cJSON *jsonPeriod = NULL;
- for(size_t i = 0; i < acl->prdRecrLen; i++)
+ while (cbor_value_is_valid(&aclistMap))
+ {
+ char* acName = NULL;
+ size_t acLen = 0;
+ CborType acType = cbor_value_get_type(&aclistMap);
+ if (acType == CborTextStringType)
{
- jsonPeriod = cJSON_GetArrayItem(jsonPeriodObj, i);
- VERIFY_NON_NULL(TAG, jsonPeriod, ERROR);
-
- jsonObjLen = strlen(jsonPeriod->valuestring) + 1;
- acl->periods[i] = (char*)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, acl->periods[i], ERROR);
- OICStrcpy(acl->periods[i], jsonObjLen,
- jsonPeriod->valuestring);
+ cborFindResult = cbor_value_dup_text_string(&aclistMap, &acName, &acLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACLIST Map.");
+ cborFindResult = cbor_value_advance(&aclistMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACLIST Map.");
}
- }
- }
-
- //Recurrence -- Not mandatory
- cJSON *jsonRecurObj = cJSON_GetObjectItem(jsonAcl,
- OIC_JSON_RECURRENCES_NAME);
- if(jsonRecurObj)
- {
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonRecurObj->type,
- ERROR);
+ if(acName)
+ {
+ if (strcmp(acName, OIC_JSON_ACES_NAME) == 0)
+ {
- if(acl->prdRecrLen > 0)
- {
- acl->recurrences = (char**)OICCalloc(acl->prdRecrLen,
- sizeof(char*));
- VERIFY_NON_NULL(TAG, acl->recurrences, ERROR);
+ // Enter ACES Array
+ CborValue aclArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+ cborFindResult = cbor_value_enter_container(&aclistMap, &aclArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Array.");
+
+ int acesCount = 0;
+ while (cbor_value_is_valid(&aclArray))
+ {
+ acesCount++;
+
+ CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+ cborFindResult = cbor_value_enter_container(&aclArray, &aclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering ACL Map.");
+ OicSecAcl_t *acl = NULL;
+
+ if(acesCount == 1)
+ {
+ acl = headAcl;
+ }
+ else
+ {
+ acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
+ OicSecAcl_t *temp = headAcl;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = acl;
+ }
+ VERIFY_NON_NULL(TAG, acl, ERROR);
+
+ while (cbor_value_is_valid(&aclMap))
+ {
+ char* name = NULL;
+ size_t len = 0;
+ CborType type = cbor_value_get_type(&aclMap);
+ if (type == CborTextStringType)
+ {
+ cborFindResult = cbor_value_dup_text_string(&aclMap, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in ACL Map.");
+ cborFindResult = cbor_value_advance(&aclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in ACL Map.");
+ }
+ if (name)
+ {
+ // Subject -- Mandatory
+ if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
+ {
+ char *subject = NULL;
+ cborFindResult = cbor_value_dup_text_string(&aclMap, &subject, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subject Value.");
+ if(strcmp(subject, WILDCARD_RESOURCE_URI) == 0)
+ {
+ acl->subject.id[0] = '*';
+ }
+ else
+ {
+ ret = ConvertStrToUuid(subject, &acl->subject);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ }
+ OICFree(subject);
+ }
+
+ // Resources -- Mandatory
+ if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
+ {
+ CborValue resources = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&aclMap, &acl->resourcesLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Resource Array Len Value.");
+ cborFindResult = cbor_value_enter_container(&aclMap, &resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering a Resource Array.");
+
+ acl->resources = (char **) OICMalloc(acl->resourcesLen * sizeof(char*));
+ VERIFY_NON_NULL(TAG, acl->resources, ERROR);
+ int i = 0;
+ while (cbor_value_is_valid(&resources))
+ {
+ // rMap
+ CborValue rMap = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&resources, &rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
+
+
+ while(cbor_value_is_valid(&rMap))
+ {
+ char *rMapName = NULL;
+ size_t rMapNameLen = 0;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
+ cborFindResult = cbor_value_advance(&rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
+
+ // "href"
+ if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecAcl_t based on RAML spec.
+ cborFindResult = cbor_value_dup_text_string(&rMap, &acl->resources[i++], &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
+ }
+ // "rel"
+ if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecAcl_t based on RAML spec.
+ char *relData = NULL;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &relData, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
+ OICFree(relData);
+ }
+ // "rt"
+ if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecAcl_t and assign based on RAML spec.
+ char *rtData = NULL;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
+ OICFree(rtData);
+ }
+
+ // "if"
+ if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecAcl_t and assign based on RAML spec.
+ char *ifData = NULL;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
+ OICFree(ifData);
+ }
+
+ if (cbor_value_is_valid(&rMap))
+ {
+ cborFindResult = cbor_value_advance(&rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
+ }
+ OICFree(rMapName);
+ }
+
+ if (cbor_value_is_valid(&resources))
+ {
+ cborFindResult = cbor_value_advance(&resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
+ }
+ }
+ }
+
+ // Permissions -- Mandatory
+ if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
+ {
+ cborFindResult = cbor_value_get_uint64(&aclMap, (uint64_t *) &acl->permission);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a PERM Value.");
+ }
+
+ // Period -- Not mandatory
+ if (strcmp(name, OIC_JSON_PERIOD_NAME) == 0)
+ {
+ CborValue period = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&aclMap, &acl->prdRecrLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period Array Len.");
+ cborFindResult = cbor_value_enter_container(&aclMap, &period);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period Array Map.");
+ acl->periods = (char**)OICCalloc(acl->prdRecrLen, sizeof(char*));
+ VERIFY_NON_NULL(TAG, acl->periods, ERROR);
+ int i = 0;
+ while (cbor_value_is_text_string(&period))
+ {
+ cborFindResult = cbor_value_dup_text_string(&period, &acl->periods[i++],
+ &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding a Period Array Value.");
+ cborFindResult = cbor_value_advance(&period);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a Period Array.");
+ }
+ }
+
+ // Recurrence -- Not mandatory
+ if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0)
+ {
+ CborValue recurrences = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&aclMap, &recurrences);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array.");
+ acl->recurrences = (char**)OICCalloc(acl->prdRecrLen, sizeof(char*));
+ VERIFY_NON_NULL(TAG, acl->recurrences, ERROR);
+ int i = 0;
+ while (cbor_value_is_text_string(&recurrences))
+ {
+ cborFindResult = cbor_value_dup_text_string(&recurrences,
+ &acl->recurrences[i++], &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Adding Recurrence Array Value.");
+ cborFindResult = cbor_value_advance(&recurrences);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Closing Recurrence Array.");
+ }
+ }
+
+ OICFree(name);
+ }
+
+ if (type != CborMapType && cbor_value_is_valid(&aclMap))
+ {
+ cborFindResult = cbor_value_advance(&aclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Array.");
+ }
+ }
+
+ acl->next = NULL;
+
+ if (cbor_value_is_valid(&aclArray))
+ {
+ cborFindResult = cbor_value_advance(&aclArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Array.");
+ }
+ }
+ }
+ OICFree(acName);
+ }
- cJSON *jsonRecur = NULL;
- for(size_t i = 0; i < acl->prdRecrLen; i++)
+ if (cbor_value_is_valid(&aclistMap))
{
- jsonRecur = cJSON_GetArrayItem(jsonRecurObj, i);
- VERIFY_NON_NULL(TAG, jsonRecur, ERROR);
- jsonObjLen = strlen(jsonRecur->valuestring) + 1;
- acl->recurrences[i] = (char*)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, acl->recurrences[i], ERROR);
- OICStrcpy(acl->recurrences[i], jsonObjLen,
- jsonRecur->valuestring);
+ cborFindResult = cbor_value_advance(&aclistMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACLIST Map.");
}
}
}
- // Owners -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_OWNERS_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
-
- acl->ownersLen = (size_t)cJSON_GetArraySize(jsonObj);
- VERIFY_SUCCESS(TAG, acl->ownersLen > 0, ERROR);
- acl->owners = (OicUuid_t*)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, (acl->owners), ERROR);
-
- idxx = 0;
- do
+ // TODO : Need to modify headAcl->owners[0].id to headAcl->rowner based on RAML spec.
+ if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0)
{
- cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
- VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
-
- outLen = 0;
- b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
- sizeof(base64Buff), &outLen);
-
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(acl->owners[idxx].id)),
- ERROR);
- memcpy(acl->owners[idxx].id, base64Buff, outLen);
- } while ( ++idxx < acl->ownersLen);
-
- prevAcl = acl;
- } while( ++idx < numAcl);
+ char *stRowner = NULL;
+ cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
+ ret = ConvertStrToUuid(stRowner, &headAcl->rownerID);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(stRowner);
+ }
+ OICFree(tagName);
+ }
+ if (cbor_value_is_valid(&aclMap))
+ {
+ cborFindResult = cbor_value_advance(&aclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing ACL Map.");
+ }
}
- ret = OC_STACK_OK;
-
exit:
- cJSON_Delete(jsonRoot);
- if (OC_STACK_OK != ret)
+ if (cborFindResult != CborNoError)
{
+ OIC_LOG(ERROR, TAG, "Failed to CBORPayloadToAcl");
DeleteACLList(headAcl);
headAcl = NULL;
}
return headAcl;
}
-static bool UpdatePersistentStorage(const OicSecAcl_t *acl)
-{
- // Convert ACL data into JSON for update to persistent storage
- char *jsonStr = BinToAclJSON(acl);
- if (jsonStr)
- {
- cJSON *jsonAcl = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- if ((jsonAcl) && (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl)))
- {
- return true;
- }
- cJSON_Delete(jsonAcl);
- }
- return false;
-}
-
-/*
+/**
* This method removes ACE for the subject and resource from the ACL
*
- * @param subject - subject of the ACE
- * @param resource - resource of the ACE
+ * @param subject of the ACE
+ * @param resource of the ACE
*
* @return
- * OC_STACK_RESOURCE_DELETED on success
- * OC_STACK_NO_RESOURC on failure to find the appropriate ACE
- * OC_STACK_INVALID_PARAM on invalid parameter
+ * ::OC_STACK_RESOURCE_DELETED on success
+ * ::OC_STACK_NO_RESOURCE on failure to find the appropriate ACE
+ * ::OC_STACK_INVALID_PARAM on invalid parameter
*/
-static OCStackResult RemoveACE(const OicUuid_t * subject,
- const char * resource)
+static OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
{
OIC_LOG(DEBUG, TAG, "IN RemoveACE");
bool deleteFlag = false;
OCStackResult ret = OC_STACK_NO_RESOURCE;
- if(memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
+ if (memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
{
- OIC_LOG_V (ERROR, TAG, "%s received invalid parameter", __func__ );
+ OIC_LOG_V(ERROR, TAG, "%s received invalid parameter", __func__ );
return OC_STACK_INVALID_PARAM;
}
//If resource is NULL then delete all the ACE for the subject.
- if(NULL == resource || resource[0] == '\0')
+ if (NULL == resource || resource[0] == '\0')
{
LL_FOREACH_SAFE(gAcl, acl, tempAcl)
{
- if(memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
+ if (memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
{
LL_DELETE(gAcl, acl);
FreeACE(acl);
//the resource array
LL_FOREACH_SAFE(gAcl, acl, tempAcl)
{
- if(memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
+ if (memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
{
- if(1 == acl->resourcesLen && strcmp(acl->resources[0], resource) == 0)
+ if (1 == acl->resourcesLen && strcmp(acl->resources[0], resource) == 0)
{
LL_DELETE(gAcl, acl);
FreeACE(acl);
}
else
{
- int resPos = -1;
+ size_t resPos = -1;
size_t i;
- for(i = 0; i < acl->resourcesLen; i++)
+ for (i = 0; i < acl->resourcesLen; i++)
{
- if(strcmp(acl->resources[i], resource) == 0)
+ if (strcmp(acl->resources[i], resource) == 0)
{
resPos = i;
break;
}
}
- if((0 <= resPos))
+ if (0 <= (int) resPos)
{
OICFree(acl->resources[resPos]);
acl->resources[resPos] = NULL;
acl->resourcesLen -= 1;
- for(i = (size_t)resPos; i < acl->resourcesLen; i++)
+ for (i = resPos; i < acl->resourcesLen; i++)
{
- acl->resources[i] = acl->resources[i+1];
+ acl->resources[i] = acl->resources[i + 1];
}
deleteFlag = true;
break;
}
}
- if(deleteFlag)
+ if (deleteFlag)
{
- if(UpdatePersistentStorage(gAcl))
+ // In case of unit test do not update persistant storage.
+ if (memcmp(subject->id, &WILDCARD_SUBJECT_B64_ID, sizeof(subject->id)) == 0)
{
ret = OC_STACK_RESOURCE_DELETED;
}
+ else
+ {
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
+ {
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size))
+ {
+ ret = OC_STACK_RESOURCE_DELETED;
+ }
+ OICFree(payload);
+ }
+ }
}
return ret;
}
-/*
+/**
* This method parses the query string received for REST requests and
* retrieves the 'subject' field.
*
*/
static bool GetSubjectFromQueryString(const char *query, OicUuid_t *subject)
{
- OicParseQueryIter_t parseIter = {.attrPos=NULL};
+ OicParseQueryIter_t parseIter = { .attrPos = NULL };
- ParseQueryIterInit((unsigned char *)query, &parseIter);
+ ParseQueryIterInit((unsigned char *) query, &parseIter);
-
- while(GetNextQuery(&parseIter))
+ while (GetNextQuery (&parseIter))
{
- if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME, parseIter.attrLen) == 0)
+ if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_SUBJECTID_NAME, parseIter.attrLen) == 0)
{
VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
- b64Ret = b64Decode((char *)parseIter.valPos, parseIter.valLen, base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (B64_OK == b64Ret && outLen <= sizeof(subject->id)), ERROR);
- memcpy(subject->id, base64Buff, outLen);
-
+ memcpy(subject->id, parseIter.valPos, parseIter.valLen);
return true;
}
}
exit:
- return false;
+ return false;
}
-/*
+/**
* This method parses the query string received for REST requests and
* retrieves the 'resource' field.
*
*/
static bool GetResourceFromQueryString(const char *query, char *resource, size_t resourceSize)
{
- OicParseQueryIter_t parseIter = {.attrPos=NULL};
+ OicParseQueryIter_t parseIter = { .attrPos = NULL };
- ParseQueryIterInit((unsigned char *)query, &parseIter);
+ ParseQueryIterInit((unsigned char *) query, &parseIter);
- while(GetNextQuery(&parseIter))
+ while (GetNextQuery (&parseIter))
{
- if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen) == 0)
+ if (strncasecmp((char *) parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen)
+ == 0)
{
VERIFY_SUCCESS(TAG, 0 != parseIter.valLen, ERROR);
- OICStrcpy(resource, resourceSize, (char *)parseIter.valPos);
+ OICStrcpy(resource, resourceSize, (char *) parseIter.valPos);
return true;
}
return false;
}
-
-
-static OCEntityHandlerResult HandleACLGetRequest (const OCEntityHandlerRequest * ehRequest)
+static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
{
- OCEntityHandlerResult ehRet = OC_EH_ERROR;
- char* jsonStr = NULL;
+ OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
+ uint8_t* payload = NULL;
+ size_t size = 0;
+ OCEntityHandlerResult ehRet;
// Process the REST querystring parameters
- if(ehRequest->query)
+ if (ehRequest->query)
{
- OIC_LOG (DEBUG, TAG, "HandleACLGetRequest processing query");
+ OIC_LOG(DEBUG, TAG, "HandleACLGetRequest processing query");
- OicUuid_t subject = {.id={0}};
- char resource[MAX_URI_LENGTH] = {0};
+ OicUuid_t subject = {.id= { 0 } };
+ char resource[MAX_URI_LENGTH] = { 0 };
OicSecAcl_t *savePtr = NULL;
const OicSecAcl_t *currentAce = NULL;
// 'Subject' field is MUST for processing a querystring in REST request.
- VERIFY_SUCCESS(TAG,
- true == GetSubjectFromQueryString(ehRequest->query, &subject),
- ERROR);
+ VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR);
GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
* Below code needs to be updated for scenarios when Subject have
* multiple ACE's in ACL resource.
*/
- while((currentAce = GetACLResourceData(&subject, &savePtr)))
+ while ((currentAce = GetACLResourceData(&subject, &savePtr)))
{
/*
* If REST querystring contains a specific resource, we need
*/
if (resource[0] != '\0')
{
- for(size_t n = 0; n < currentAce->resourcesLen; n++)
+ for (size_t n = 0; n < currentAce->resourcesLen; n++)
{
- if((currentAce->resources[n]) &&
- (0 == strcmp(resource, currentAce->resources[n]) ||
- 0 == strcmp(WILDCARD_RESOURCE_URI, currentAce->resources[n])))
+ if ((currentAce->resources[n])
+ && (0 == strcmp(resource, currentAce->resources[n])
+ || 0 == strcmp(WILDCARD_RESOURCE_URI, currentAce->resources[n])))
{
- // Convert ACL data into JSON for transmission
- jsonStr = BinToAclJSON(currentAce);
+ // Convert ACL data into CBOR format for transmission
+ if (OC_STACK_OK != AclToCBORPayload(currentAce, &payload, &size))
+ {
+ ehRet = OC_EH_ERROR;
+ }
goto exit;
}
}
}
else
{
- // Convert ACL data into JSON for transmission
- jsonStr = BinToAclJSON(currentAce);
+ // Convert ACL data into CBOR format for transmission
+ if (OC_STACK_OK != AclToCBORPayload(currentAce, &payload, &size))
+ {
+ ehRet = OC_EH_ERROR;
+ }
goto exit;
}
}
}
else
{
- // Convert ACL data into JSON for transmission
- jsonStr = BinToAclJSON(gAcl);
+ // Convert ACL data into CBOR format for transmission.
+ if (OC_STACK_OK != AclToCBORPayload(gAcl, &payload, &size))
+ {
+ ehRet = OC_EH_ERROR;
+ }
}
-
exit:
- ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
+ // A device should always have a default acl. Therefore, payload should never be NULL.
+ ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
// Send response payload to request originator
- SendSRMResponse(ehRequest, ehRet, jsonStr);
-
- OICFree(jsonStr);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed for HandleACLGetRequest");
+ }
+ OICFree(payload);
- OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
+ OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
return ehRet;
}
-static OCEntityHandlerResult HandleACLPostRequest (const OCEntityHandlerRequest * ehRequest)
+static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *ehRequest)
{
+ OIC_LOG(INFO, TAG, "HandleACLPostRequest processing the request");
OCEntityHandlerResult ehRet = OC_EH_ERROR;
- // Convert JSON ACL data into binary. This will also validate the ACL data received.
- OicSecAcl_t* newAcl = JSONToAclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
-
- if (newAcl)
+ // Convert CBOR into ACL data and update to SVR buffers. This will also validate the ACL data received.
+ uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
+ if (payload)
{
- // Append the new ACL to existing ACL
- LL_APPEND(gAcl, newAcl);
-
- if(UpdatePersistentStorage(gAcl))
+ OicSecAcl_t *newAcl = CBORPayloadToAcl(payload, size);
+ if (newAcl)
{
- ehRet = OC_EH_RESOURCE_CREATED;
+ // Append the new ACL to existing ACL
+ LL_APPEND(gAcl, newAcl);
+ size_t size = 0;
+ // In case of unit test do not update persistant storage.
+ if (memcmp(newAcl->subject.id, &WILDCARD_SUBJECT_ID, sizeof(newAcl->subject.id)) == 0
+ || memcmp(newAcl->subject.id, &WILDCARD_SUBJECT_B64_ID, sizeof(newAcl->subject.id)) == 0)
+ {
+ ehRet = OC_EH_RESOURCE_CREATED;
+ }
+ else
+ {
+ uint8_t *cborPayload = NULL;
+ if (OC_STACK_OK == AclToCBORPayload(gAcl, &cborPayload, &size))
+ {
+ if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size) == OC_STACK_OK)
+ {
+ ehRet = OC_EH_RESOURCE_CREATED;
+ }
+ OICFree(cborPayload);
+ }
+ }
}
}
// Send payload to request originator
- SendSRMResponse(ehRequest, ehRet, NULL);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleACLPostRequest");
+ }
- OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
+ OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
return ehRet;
}
static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest *ehRequest)
{
- OIC_LOG (DEBUG, TAG, "Processing ACLDeleteRequest");
+ OIC_LOG(DEBUG, TAG, "Processing ACLDeleteRequest");
OCEntityHandlerResult ehRet = OC_EH_ERROR;
- OicUuid_t subject = {.id={0}};
- char resource[MAX_URI_LENGTH] = {0};
+ OicUuid_t subject = { .id= { 0 } };
+ char resource[MAX_URI_LENGTH] = { 0 };
VERIFY_NON_NULL(TAG, ehRequest->query, ERROR);
// 'Subject' field is MUST for processing a querystring in REST request.
- VERIFY_SUCCESS(TAG,
- true == GetSubjectFromQueryString(ehRequest->query, &subject),
- ERROR);
+ VERIFY_SUCCESS(TAG, true == GetSubjectFromQueryString(ehRequest->query, &subject), ERROR);
GetResourceFromQueryString(ehRequest->query, resource, sizeof(resource));
- if(OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
+ if (OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
{
ehRet = OC_EH_RESOURCE_DELETED;
}
exit:
// Send payload to request originator
- SendSRMResponse(ehRequest, ehRet, NULL);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleACLDeleteRequest");
+ }
return ehRet;
}
-/*
- * This internal method is the entity handler for ACL resources and
- * will handle REST request (GET/PUT/POST/DEL) for them.
- */
-OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest,
- void* callbackParameter)
+OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest,
+ void* callbackParameter)
{
OIC_LOG(DEBUG, TAG, "Received request ACLEntityHandler");
(void)callbackParameter;
if (flag & OC_REQUEST_FLAG)
{
// TODO : Handle PUT method
- OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
+ OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
switch (ehRequest->method)
{
case OC_REST_GET:
default:
ehRet = OC_EH_ERROR;
- SendSRMResponse(ehRequest, ehRet, NULL);
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
}
}
return ehRet;
}
-/*
+/**
* This internal method is used to create '/oic/sec/acl' resource.
*/
-OCStackResult CreateACLResource()
+static OCStackResult CreateACLResource()
{
OCStackResult ret;
if (OC_STACK_OK != ret)
{
- OIC_LOG (FATAL, TAG, "Unable to instantiate ACL resource");
+ OIC_LOG(FATAL, TAG, "Unable to instantiate ACL resource");
DeInitACLResource();
}
return ret;
}
-/*
- * This internal method is to retrieve the default ACL.
- * If SVR database in persistent storage got corrupted or
- * is not available for some reason, a default ACL is created
- * which allows user to initiate ACL provisioning again.
- */
-OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
+// This function sets the default ACL and is defined for the unit test only.
+OCStackResult SetDefaultACL(OicSecAcl_t *acl)
+{
+ gAcl = acl;
+ return OC_STACK_OK;
+}
+
+OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
{
OCStackResult ret = OC_STACK_ERROR;
- OicUuid_t ownerId = {.id = {0}};
+ OicUuid_t ownerId = { .id = { 0 } };
/*
* TODO In future, when new virtual resources will be added in OIC
return OC_STACK_INVALID_PARAM;
}
- OicSecAcl_t *acl = (OicSecAcl_t *)OICCalloc(1, sizeof(OicSecAcl_t));
+ OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
VERIFY_NON_NULL(TAG, acl, ERROR);
// Subject -- Mandatory
memcpy(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(acl->subject));
// Resources -- Mandatory
- acl->resourcesLen = sizeof(rsrcs)/sizeof(rsrcs[0]);
+ acl->resourcesLen = sizeof(rsrcs) / sizeof(rsrcs[0]);
- acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
+ acl->resources = (char**) OICCalloc(acl->resourcesLen, sizeof(char*));
VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
- for (size_t i = 0; i < acl->resourcesLen; i++)
+ for (size_t i = 0; i < acl->resourcesLen; i++)
{
size_t len = strlen(rsrcs[i]) + 1;
- acl->resources[i] = (char*)OICMalloc(len * sizeof(char));
+ acl->resources[i] = (char*) OICMalloc(len * sizeof(char));
VERIFY_NON_NULL(TAG, (acl->resources[i]), ERROR);
OICStrcpy(acl->resources[i], len, rsrcs[i]);
}
acl->recurrences = NULL;
// Device ID is the owner of this default ACL
- ret = GetDoxmDeviceID( &ownerId);
- VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
+ if (GetDoxmResourceData() != NULL)
+ {
+ ret = GetDoxmDeviceID(&ownerId);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
+ }
+ else
+ {
+ OCRandomUuidResult rdm = OCGenerateUuid(ownerId.id);
+ VERIFY_SUCCESS(TAG, RAND_UUID_OK == rdm, FATAL);
+ }
- acl->ownersLen = 1;
- acl->owners = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, (acl->owners), ERROR);
- memcpy(acl->owners, &ownerId, sizeof(OicUuid_t));
+ memcpy(&acl->rownerID, &ownerId, sizeof(OicUuid_t));
acl->next = NULL;
return ret;
}
-/**
- * Initialize ACL resource by loading data from persistent storage.
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult InitACLResource()
{
OCStackResult ret = OC_STACK_ERROR;
- // Read ACL resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
-
- if (jsonSVRDatabase)
+ uint8_t *data = NULL;
+ size_t size = 0;
+ ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &data, &size);
+ // If database read failed
+ if (ret != OC_STACK_OK)
{
- // Convert JSON ACL into binary format
- gAcl = JSONToAclBin(jsonSVRDatabase);
- OICFree(jsonSVRDatabase);
+ OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
+ if (data)
+ {
+ // Read ACL resource from PS
+ gAcl = CBORPayloadToAcl(data, size);
}
/*
* If SVR database in persistent storage got corrupted or
* is not available for some reason, a default ACL is created
* which allows user to initiate ACL provisioning again.
*/
- if (!jsonSVRDatabase || !gAcl)
+ if (!gAcl)
{
GetDefaultACL(&gAcl);
// TODO Needs to update persistent storage
return ret;
}
-/**
- * Perform cleanup for ACL resources.
- *
- * @retval none
- */
-void DeInitACLResource()
+OCStackResult DeInitACLResource()
{
- OCDeleteResource(gAclHandle);
+ OCStackResult ret = OCDeleteResource(gAclHandle);
gAclHandle = NULL;
- DeleteACLList(gAcl);
- gAcl = NULL;
+ if (gAcl)
+ {
+ DeleteACLList(gAcl);
+ gAcl = NULL;
+ }
+ return ret;
}
-/**
- * This method is used by PolicyEngine to retrieve ACL for a Subject.
- *
- * @param subjectId ID of the subject for which ACL is required.
- * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
- * successive calls for same subjectId.
- *
- * @retval reference to @ref OicSecAcl_t if ACL is found, else NULL
- *
- * @note On the first call to @ref GetACLResourceData, savePtr should point to NULL
- */
const OicSecAcl_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAcl_t **savePtr)
{
OicSecAcl_t *acl = NULL;
OicSecAcl_t *begin = NULL;
- if ( NULL == subjectId)
+ if (NULL == subjectId)
{
return NULL;
}
return NULL;
}
-
-OCStackResult InstallNewACL(const char* newJsonStr)
+OCStackResult InstallNewACL(const uint8_t *cborPayload, const size_t size)
{
OCStackResult ret = OC_STACK_ERROR;
- // Convert JSON ACL data into binary. This will also validate the ACL data received.
- OicSecAcl_t* newAcl = JSONToAclBin(newJsonStr);
+ // Convert CBOR format to ACL data. This will also validate the ACL data received.
+ OicSecAcl_t* newAcl = CBORPayloadToAcl(cborPayload, size);
if (newAcl)
{
// Append the new ACL to existing ACL
LL_APPEND(gAcl, newAcl);
- // Convert ACL data into JSON for update to persistent storage
- char *jsonStr = BinToAclJSON(gAcl);
- if (jsonStr)
+ // Update persistent storage only if it is not WILDCARD_SUBJECT_ID
+ if (memcmp(newAcl->subject.id, &WILDCARD_SUBJECT_ID, sizeof(newAcl->subject.id)) == 0
+ || memcmp(newAcl->subject.id, &WILDCARD_SUBJECT_B64_ID, sizeof(newAcl->subject.id)) == 0)
{
- cJSON *jsonAcl = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- if (jsonAcl)
+ ret = OC_STACK_OK;
+ }
+ else
+ {
+ size_t size = 0;
+ uint8_t *payload = NULL;
+ if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
{
- ret = UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl);
+ if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
+ {
+ ret = OC_STACK_OK;
+ }
+ OICFree(payload);
}
- cJSON_Delete(jsonAcl);
}
}
/**
* This function generates default ACL for security resource in case of owned status.
*
- * @retval Default ACL for security resource.
+ * @return Default ACL for security resource.
*/
static OicSecAcl_t* GetSecDefaultACL()
{
VERIFY_SUCCESS(TAG, OC_STACK_OK == res, FATAL);
// Owners -- Mandatory
- newDefaultAcl->ownersLen = 1;
- newDefaultAcl->owners = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, (newDefaultAcl->owners), ERROR);
- memcpy(newDefaultAcl->owners, &ownerId, sizeof(OicUuid_t));
+ memcpy(&newDefaultAcl->rownerID, &ownerId, sizeof(OicUuid_t));
return newDefaultAcl;
exit:
* resources : '/oic/sec/doxm', '/oic/sec/pstat'
* permission : READ
*/
- OicSecAcl_t* newDefaultAcl = GetSecDefaultACL();
- if(newDefaultAcl)
+ OicSecAcl_t *newDefaultAcl = GetSecDefaultACL();
+ if (newDefaultAcl)
{
LL_APPEND(gAcl, newDefaultAcl);
- char *jsonStr = BinToAclJSON(gAcl);
- if(jsonStr)
+ size_t size = 0;
+ uint8_t *payload = NULL;
+ if (OC_STACK_OK == AclToCBORPayload(gAcl, &payload, &size))
{
- cJSON *jsonAcl = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- //Update SVR DB
- if (jsonAcl)
+ if (UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, payload, size) == OC_STACK_OK)
{
- ret = UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl);
- if(OC_STACK_OK != ret)
- {
- OIC_LOG(WARNING, TAG, "Failed to update SVR DB");
- }
+ ret = OC_STACK_OK;
}
- cJSON_Delete(jsonAcl);
+ OICFree(payload);
}
}
}
return ret;
}
+
+OCStackResult SetAclRownerId(const OicUuid_t* newROwner)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ uint8_t *cborPayload = NULL;
+ size_t size = 0;
+ OicUuid_t prevId = {.id={0}};
+
+ if(NULL == newROwner)
+ {
+ ret = OC_STACK_INVALID_PARAM;
+ }
+ if(NULL == gAcl)
+ {
+ ret = OC_STACK_NO_RESOURCE;
+ }
+
+ if(newROwner && gAcl)
+ {
+ memcpy(prevId.id, gAcl->rownerID.id, sizeof(prevId.id));
+ memcpy(gAcl->rownerID.id, newROwner->id, sizeof(newROwner->id));
+
+ ret = AclToCBORPayload(gAcl, &cborPayload, &size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ ret = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, cborPayload, size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ OICFree(cborPayload);
+ }
+
+ return ret;
+
+exit:
+ OICFree(cborPayload);
+ memcpy(gAcl->rownerID.id, prevId.id, sizeof(prevId.id));
+ return ret;
+}
+
+OCStackResult GetAclRownerId(OicUuid_t *rowneruuid)
+{
+ OCStackResult retVal = OC_STACK_ERROR;
+ if (gAcl)
+ {
+ *rowneruuid = gAcl->rownerID;
+ retVal = OC_STACK_OK;
+ }
+ return retVal;
+}
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
#include <stdlib.h>
#include <string.h>
-#include "ocstack.h"
-#include "logger.h"
#include "oic_malloc.h"
-#include "oic_string.h"
-#include "cJSON.h"
-#include "base64.h"
-#include "resourcemanager.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
#include "psinterface.h"
+#include "resourcemanager.h"
#include "utlist.h"
#include "srmresourcestrings.h"
-#include "amaclresource.h"
#include "srmutility.h"
-#include <stdlib.h>
-#include <string.h>
+#include "amaclresource.h"
#define TAG "SRM-AMACL"
-OicSecAmacl_t *gAmacl = NULL;
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching belox max cbor size. */
+static const uint16_t CBOR_SIZE = 1024;
+
+/* Max cbor size payload. */
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+/** AMACL Map size - Number of mandatory items. */
+static const uint8_t AMACL_MAP_SIZE = 3;
+static const uint8_t AMACL_RSRC_MAP_SIZE = 1;
+static const uint8_t AMACL_RLIST_MAP_SIZE = 3;
+
+static OicSecAmacl_t *gAmacl = NULL;
static OCResourceHandle gAmaclHandle = NULL;
void DeleteAmaclList(OicSecAmacl_t* amacl)
// Clean Amss
OICFree(amaclTmp1->amss);
- // Clean Owners
- OICFree(amaclTmp1->owners);
-
// Clean Amacl node itself
OICFree(amaclTmp1);
}
}
}
-/*
- * This internal method converts AMACL data into JSON format.
- *
- * Note: Caller needs to invoke 'free' when finished using the return string.
- */
-char * BinToAmaclJSON(const OicSecAmacl_t * amacl)
+static size_t OicSecAmaclCount(const OicSecAmacl_t *secAmacl)
+{
+ size_t size = 0;
+ for (const OicSecAmacl_t *amacl = secAmacl; amacl; amacl = amacl->next)
+ {
+ size++;
+ }
+ return size;
+}
+
+OCStackResult AmaclToCBORPayload(const OicSecAmacl_t *amaclS, uint8_t **cborPayload,
+ size_t *cborSize)
{
- cJSON *jsonRoot = NULL;
- char *jsonStr = NULL;
+ if (NULL == amaclS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
- if (amacl)
+ OCStackResult ret = OC_STACK_ERROR;
+ size_t cborLen = *cborSize;
+ if (0 == cborLen)
{
- jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ cborLen = CBOR_SIZE;
+ }
- cJSON *jsonAmaclArray = NULL;
- cJSON_AddItemToObject (jsonRoot, OIC_JSON_AMACL_NAME, jsonAmaclArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonAmaclArray, ERROR);
+ *cborSize = 0;
+ *cborPayload = NULL;
- while(amacl)
- {
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
-
- cJSON *jsonAmacl = cJSON_CreateObject();
-
- // Resources -- Mandatory
- cJSON *jsonRsrcArray = NULL;
- cJSON_AddItemToObject(jsonAmacl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray =
- cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
- for (unsigned int i = 0; i < amacl->resourcesLen; i++)
- {
- cJSON_AddItemToArray(jsonRsrcArray, cJSON_CreateString(amacl->resources[i]));
- }
+ CborEncoder encoder;
+ CborEncoder amaclMap;
+ int64_t cborEncoderResult = CborNoError;
+ CborEncoder rsrcMap;
+ CborEncoder rlistArray;
+ CborEncoder amss;
+ char *stRowner = NULL;
- // Amss -- Mandatory
- cJSON *jsonAmsArray = NULL;
- cJSON_AddItemToObject(jsonAmacl, OIC_JSON_AMSS_NAME, jsonAmsArray =
- cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonAmsArray, ERROR);
- for (unsigned int i = 0; i < amacl->amssLen; i++)
- {
- outLen = 0;
+ const OicSecAmacl_t *amacl = amaclS;
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
- b64Ret = b64Encode(amacl->amss[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+ // Create AMACL Map
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &amaclMap, AMACL_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMACL Map.");
- cJSON_AddItemToArray(jsonAmsArray, cJSON_CreateString(base64Buff));
- }
+ // resources -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_RESOURCES_NAME,
+ strlen(OIC_JSON_RESOURCES_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Name Tag.");
- // Owners -- Mandatory
- cJSON *jsonOwnrArray = NULL;
- cJSON_AddItemToObject(jsonAmacl, OIC_JSON_OWNERS_NAME, jsonOwnrArray =
- cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
- for (unsigned int i = 0; i < amacl->ownersLen; i++)
- {
- outLen = 0;
+ cborEncoderResult = cbor_encoder_create_map(&amaclMap, &rsrcMap, AMACL_RSRC_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
- b64Ret = b64Encode(amacl->owners[i].id, sizeof(((OicUuid_t*) 0)->id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddItemToArray(jsonOwnrArray, cJSON_CreateString(base64Buff));
- }
+ cborEncoderResult = cbor_encode_text_string(&rsrcMap, OIC_JSON_RLIST_NAME,
+ strlen(OIC_JSON_RLIST_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RLIST Name Tag.");
- // Attach current amacl node to Amacl Array
- cJSON_AddItemToArray(jsonAmaclArray, jsonAmacl);
- amacl = amacl->next;
- }
+ // TODO : Need to input array length by OicSecAmacl_t->resources->rlistLen based on spec.
+ cborEncoderResult = cbor_encoder_create_array(&rsrcMap, &rlistArray, amacl->resourcesLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RLIST Array.");
- jsonStr = cJSON_PrintUnformatted(jsonRoot);
+ // TODO : Need to add OicSecAmacl_t->rlist as array rMap based on RAML spec.
+ for (size_t i = 0; i < amacl->resourcesLen; i++)
+ {
+ // TODO : Need to create rMap structure based on RAML spec.
+ CborEncoder rMap;
+ cborEncoderResult = cbor_encoder_create_map(&rlistArray, &rMap, AMACL_RLIST_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RLIST Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
+ strlen(OIC_JSON_HREF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
+ cborEncoderResult = cbor_encode_text_string(&rMap, amacl->resources[i],
+ strlen(amacl->resources[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
+ strlen(OIC_JSON_RT_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
+
+ // TODO : Need to assign real value of RT
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
+ strlen(OIC_JSON_EMPTY_STRING));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
+ strlen(OIC_JSON_IF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
+
+ // TODO : Need to assign real value of IF
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
+ strlen(OIC_JSON_EMPTY_STRING));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
+
+ cborEncoderResult = cbor_encoder_close_container(&rlistArray, &rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RLIST Array.");
}
-exit:
- if (jsonRoot)
+ cborEncoderResult = cbor_encoder_close_container(&rsrcMap, &rlistArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RLIST Array.");
+
+
+ cborEncoderResult = cbor_encoder_close_container(&amaclMap, &rsrcMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
+
+ // TODO : Need to modify type of OicSecAmacl_t->amss based on RAML spec.
+ // ams -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_AMS_NAME,
+ strlen(OIC_JSON_AMS_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMSS Name Tag.");
+
+ cborEncoderResult = cbor_encoder_create_array(&amaclMap, &amss, amacl->amssLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMS Name Array.");
+ for (size_t i = 0; i < amacl->amssLen; i++)
{
- cJSON_Delete(jsonRoot);
+ cborEncoderResult = cbor_encode_text_string(&amss, (const char *)amacl->amss[i].id,
+ sizeof(amacl->amss[i].id));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding AMS Name Value.");
}
- return jsonStr;
-}
+ cborEncoderResult = cbor_encoder_close_container(&amaclMap, &amss);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing AMSS Array.");
+ // TODO : Need to check owner property in the RAML spec.
+ // rowner -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&amaclMap, OIC_JSON_ROWNERID_NAME,
+ strlen(OIC_JSON_ROWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding ROwnerID Name Tag.");
+ ret = ConvertUuidToStr(&amacl->rownerID, &stRowner);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&amaclMap, stRowner, strlen(stRowner));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding ROwner Value.");
+ OICFree(stRowner);
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &amaclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Amacl Map.");
-/*
- * This internal method converts JSON AMACL into binary AMACL.
- */
-OicSecAmacl_t * JSONToAmaclBin(const char * jsonStr)
+ if (CborNoError == cborEncoderResult)
+ {
+ *cborPayload = outPayload;
+ *cborSize = encoder.ptr - outPayload;
+ ret = OC_STACK_OK;
+ }
+
+exit:
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+ {
+ // reallocate and try again!
+ OICFree(outPayload);
+ outPayload = NULL;
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = AmaclToCBORPayload(amaclS, cborPayload, &cborLen);
+ if (OC_STACK_OK == ret)
+ {
+ *cborSize = cborLen;
+ ret = OC_STACK_OK;
+ }
+ }
+
+ if (CborNoError != cborEncoderResult || ret != OC_STACK_OK)
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *cborSize = 0;
+ *cborPayload = NULL;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
+}
+
+OCStackResult CBORPayloadToAmacl(const uint8_t *cborPayload, size_t size,
+ OicSecAmacl_t **secAmacl)
{
+ if (NULL == cborPayload || NULL == secAmacl || NULL != *secAmacl || 0 == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ *secAmacl = NULL;
+
OCStackResult ret = OC_STACK_ERROR;
- OicSecAmacl_t * headAmacl = NULL;
- OicSecAmacl_t * prevAmacl = NULL;
- cJSON *jsonRoot = NULL;
- cJSON *jsonAmaclArray = NULL;
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+ CborValue amaclCbor = { .parser = NULL };
+ CborParser parser = { .end = NULL };
+ CborError cborFindResult = CborNoError;
- jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ cbor_parser_init(cborPayload, size, 0, &parser, &amaclCbor);
+ OicSecAmacl_t *headAmacl = (OicSecAmacl_t *)OICCalloc(1, sizeof(OicSecAmacl_t));
- jsonAmaclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
- VERIFY_NON_NULL(TAG, jsonAmaclArray, INFO);
+ CborValue amaclMap = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&amaclCbor, &amaclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Amacl Map.");
- if (cJSON_Array == jsonAmaclArray->type)
+ while(cbor_value_is_valid(&amaclMap))
{
- int numAmacl = cJSON_GetArraySize(jsonAmaclArray);
- int idx = 0;
+ char *name = NULL;
+ size_t len = 0;
+ cborFindResult = cbor_value_dup_text_string(&amaclMap, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Amacl Data Name Tag.");
+ cborFindResult = cbor_value_advance(&amaclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Amacl Data Value.");
- VERIFY_SUCCESS(TAG, numAmacl > 0, INFO);
- do
- {
- cJSON *jsonAmacl = cJSON_GetArrayItem(jsonAmaclArray, idx);
- VERIFY_NON_NULL(TAG, jsonAmacl, ERROR);
+ //CborType type = cbor_value_get_type(&amaclMap);
- OicSecAmacl_t *amacl = (OicSecAmacl_t*)OICCalloc(1, sizeof(OicSecAmacl_t));
- VERIFY_NON_NULL(TAG, amacl, ERROR);
+ // Resources -- Mandatory
+ if (0 == strcmp(OIC_JSON_RESOURCES_NAME, name))
+ {
+ // resource map
+ CborValue rsrcMap = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&amaclMap, &rsrcMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
- headAmacl = (headAmacl) ? headAmacl : amacl;
- if (prevAmacl)
+ while(cbor_value_is_valid(&rsrcMap))
{
- prevAmacl->next = amacl;
+ // resource name
+ char *rsrcName = NULL;
+ size_t rsrcNameLen = 0;
+ cborFindResult = cbor_value_dup_text_string(&rsrcMap, &rsrcName, &rsrcNameLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Resource Data Name Tag.");
+ cborFindResult = cbor_value_advance(&rsrcMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Resource Data Value.");
+
+ // rlist
+ if (0 == strcmp(OIC_JSON_RLIST_NAME, rsrcName))
+ {
+ int i = 0;
+ // TODO : Need to assign array length to OicSecAmacl_t->resources->rlistLen based of RAML spec.
+ cborFindResult = cbor_value_get_array_length(&rsrcMap, &headAmacl->resourcesLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rlist Array Len.");
+
+ CborValue rsrcArray = { .parser = NULL };
+
+ // rlist array
+ cborFindResult = cbor_value_enter_container(&rsrcMap, &rsrcArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Rlist Array");
+
+ // TODO : Need to check data structure of OicSecAmacl_t based on RAML spec.
+ headAmacl->resources = (char **) OICCalloc(headAmacl->resourcesLen, sizeof(*headAmacl->resources));
+ VERIFY_NON_NULL(TAG, headAmacl->resources, ERROR);
+
+ while (cbor_value_is_valid(&rsrcArray))
+ {
+ // rMap
+ CborValue rMap = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&rsrcArray, &rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Rlist Map");
+
+ while(cbor_value_is_valid(&rMap))
+ {
+ char *rMapName = NULL;
+ size_t rMapNameLen = 0;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
+ cborFindResult = cbor_value_advance(&rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
+
+ // "href"
+ if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecAmacl_t based on RAML spec.
+ cborFindResult = cbor_value_dup_text_string(&rMap, &headAmacl->resources[i++], &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
+ }
+
+ // "rt"
+ if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecAmacl_t and assign based on RAML spec.
+ char *rtData = NULL;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
+ OICFree(rtData);
+ }
+
+ // "if"
+ if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecAmacl_t and assign based on RAML spec.
+ char *ifData = NULL;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
+ OICFree(ifData);
+ }
+
+ if (cbor_value_is_valid(&rMap))
+ {
+ cborFindResult = cbor_value_advance(&rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
+ }
+ OICFree(rMapName);
+ }
+
+ if (cbor_value_is_valid(&rsrcArray))
+ {
+ cborFindResult = cbor_value_advance(&rsrcArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Array.");
+ }
+ }
+ }
+
+ if (cbor_value_is_valid(&rsrcMap))
+ {
+ cborFindResult = cbor_value_advance(&rsrcMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Resource Map.");
+ }
+ OICFree(rsrcName);
}
- size_t jsonObjLen = 0;
- cJSON *jsonObj = NULL;
-
- // Resources -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
-
- amacl->resourcesLen = (size_t)cJSON_GetArraySize(jsonObj);
- VERIFY_SUCCESS(TAG, amacl->resourcesLen > 0, ERROR);
- amacl->resources = (char**)OICCalloc(amacl->resourcesLen, sizeof(char*));
- VERIFY_NON_NULL(TAG, (amacl->resources), ERROR);
+ }
- size_t idxx = 0;
- do
+ // TODO : Need to modify type of OicSecAmacl_t->amss based on RAML spec.
+ // Ams -- Mandatory
+ if (0 == strcmp(OIC_JSON_AMS_NAME, name))
+ {
+ int i = 0;
+ CborValue amsArray = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&amaclMap, &headAmacl->amssLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMS Array Len.");
+ cborFindResult = cbor_value_enter_container(&amaclMap, &amsArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering AMS Array Container.");
+ headAmacl->amss = (OicUuid_t *)OICCalloc(headAmacl->amssLen, sizeof(*headAmacl->amss));
+ VERIFY_NON_NULL(TAG, headAmacl->amss, ERROR);
+ while (cbor_value_is_valid(&amsArray))
{
- cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
- VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
-
- jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
- amacl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, (amacl->resources[idxx]), ERROR);
- OICStrcpy(amacl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
- } while ( ++idxx < amacl->resourcesLen);
+ char *amssId = NULL;
+ cborFindResult = cbor_value_dup_text_string(&amsArray, &amssId, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMS Id.");
+ cborFindResult = cbor_value_advance(&amsArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing AMS.");
+ memcpy(headAmacl->amss[i++].id, (OicUuid_t *)amssId, len);
+ OICFree(amssId);
+ }
+ }
- // Amss -- Mandatory
- VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_AMSS_NAME,
- &(amacl->amssLen), &(amacl->amss)), ERROR);
+ // Rowner -- Mandatory
+ if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name))
+ {
+ char *stRowner = NULL;
+ cborFindResult = cbor_value_dup_text_string(&amaclMap, &stRowner, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ROwner Value.");
- // Owners -- Mandatory
- VERIFY_SUCCESS( TAG, OC_STACK_OK == AddUuidArray(jsonAmacl, OIC_JSON_OWNERS_NAME,
- &(amacl->ownersLen), &(amacl->owners)), ERROR);
+ ret = ConvertStrToUuid(stRowner, &headAmacl->rownerID);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(stRowner);
+ }
- prevAmacl = amacl;
- } while( ++idx < numAmacl);
+ //if (CborMapType != type && cbor_value_is_valid(&amaclMap))
+ if (cbor_value_is_valid(&amaclMap))
+ {
+ cborFindResult = cbor_value_advance(&amaclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Amacl Map.");
+ }
+ OICFree(name);
}
+ *secAmacl = headAmacl;
ret = OC_STACK_OK;
exit:
- cJSON_Delete(jsonRoot);
- if (OC_STACK_OK != ret)
+ if (CborNoError != cborFindResult)
{
DeleteAmaclList(headAmacl);
headAmacl = NULL;
+ *secAmacl = NULL;
+ ret = OC_STACK_ERROR;
}
- return headAmacl;
+ return ret;
}
static OCEntityHandlerResult HandleAmaclGetRequest (const OCEntityHandlerRequest * ehRequest)
{
// Convert Amacl data into JSON for transmission
- char* jsonStr = BinToAmaclJSON(gAmacl);
+ size_t size = 0;
+ uint8_t *cborPayload = NULL;
+ OCStackResult res = AmaclToCBORPayload(gAmacl, &cborPayload, &size);
- OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
+ OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
// Send response payload to request originator
- SendSRMResponse(ehRequest, ehRet, jsonStr);
-
- OICFree(jsonStr);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, cborPayload, size))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleAmaclGetRequest");
+ }
+ OICFree(cborPayload);
OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
return ehRet;
{
OCEntityHandlerResult ehRet = OC_EH_ERROR;
- // Convert JSON Amacl data into binary. This will also validate the Amacl data received.
- OicSecAmacl_t* newAmacl = JSONToAmaclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
-
- if (newAmacl)
+ // Convert CBOR Amacl data into binary. This will also validate the Amacl data received.
+ uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
+ if (payload)
{
- // Append the new Amacl to existing Amacl
- LL_APPEND(gAmacl, newAmacl);
-
- // Convert Amacl data into JSON for update to persistent storage
- char *jsonStr = BinToAmaclJSON(gAmacl);
- if (jsonStr)
+ OicSecAmacl_t *newAmacl = NULL;
+ OCStackResult res = CBORPayloadToAmacl(payload, size, &newAmacl);
+ if (newAmacl && OC_STACK_OK == res)
{
- cJSON *jsonAmacl = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- if ((jsonAmacl) &&
- (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_AMACL_NAME, jsonAmacl)))
+ // Append the new Amacl to existing Amacl
+ LL_APPEND(gAmacl, newAmacl);
+ size_t size = 0;
+ // Convert Amacl data into JSON for update to persistent storage.
+ uint8_t *cborPayload = NULL;
+ res = AmaclToCBORPayload(gAmacl, &cborPayload, &size);
+ if (cborPayload && (OC_STACK_OK == res) &&
+ (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_AMACL_NAME, cborPayload, size)))
{
ehRet = OC_EH_RESOURCE_CREATED;
}
- cJSON_Delete(jsonAmacl);
+ OICFree(cborPayload);
}
+ OICFree(payload);
}
// Send payload to request originator
- SendSRMResponse(ehRequest, ehRet, NULL);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleAmaclPostRequest");
+ }
- OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
+ OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
return ehRet;
}
-/*
+/**
* This internal method is the entity handler for Amacl resources and
* will handle REST request (GET/PUT/POST/DEL) for them.
*/
-OCEntityHandlerResult AmaclEntityHandler (OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest,
- void* callbackParameter)
+static OCEntityHandlerResult AmaclEntityHandler (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void* callbackParameter)
{
(void) callbackParameter;
OCEntityHandlerResult ehRet = OC_EH_ERROR;
default:
ehRet = OC_EH_ERROR;
- SendSRMResponse(ehRequest, ehRet, NULL);
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
}
}
return ehRet;
}
-/*
+/**
* This internal method is used to create '/oic/sec/amacl' resource.
*/
-OCStackResult CreateAmaclResource()
+static OCStackResult CreateAmaclResource()
{
- OCStackResult ret;
-
- ret = OCCreateResource(&gAmaclHandle,
- OIC_RSRC_TYPE_SEC_AMACL,
- OIC_MI_DEF,
- OIC_RSRC_AMACL_URI,
- AmaclEntityHandler,
- NULL,
- OC_OBSERVABLE);
+ OCStackResult ret = OCCreateResource(&gAmaclHandle,
+ OIC_RSRC_TYPE_SEC_AMACL,
+ OIC_MI_DEF,
+ OIC_RSRC_AMACL_URI,
+ AmaclEntityHandler,
+ NULL,
+ OC_OBSERVABLE);
if (OC_STACK_OK != ret)
{
return ret;
}
-/**
- * Initialize Amacl resource by loading data from persistent storage.
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult InitAmaclResource()
{
OCStackResult ret = OC_STACK_ERROR;
- // Read Amacl resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
+ uint8_t *data = NULL;
+ size_t size = 0;
+ ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_AMACL_NAME, &data, &size);
- if (jsonSVRDatabase)
+ // If database read failed
+ if (OC_STACK_OK != ret)
{
- // Convert JSON Amacl into binary format
- gAmacl = JSONToAmaclBin(jsonSVRDatabase);
- OICFree(jsonSVRDatabase);
+ OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
+ if (data)
+ {
+ // Read AMACL resource from PS
+ ret = CBORPayloadToAmacl(data, size, &gAmacl);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(DEBUG, TAG, "ReadAMACLresourcefromPS failed");
+ }
+ OICFree(data);
}
// Instantiate 'oic/sec/amacl' resource
return ret;
}
-/**
- * Perform cleanup for Amacl resources.
- *
- * @retval none
- */
void DeInitAmaclResource()
{
OCDeleteResource(gAmaclHandle);
gAmacl = NULL;
}
-
OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsDeviceId)
{
OicSecAmacl_t *amacl = NULL;
{
for(size_t i = 0; i < amacl->resourcesLen; i++)
{
- if (strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])) == 0)
+ if (0 == strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])))
{
//Returning the ID of the first AMS service for the resource
memcpy(amsDeviceId, &amacl->amss[0], sizeof(*amsDeviceId));
exit:
return OC_STACK_ERROR;
}
+
+OCStackResult SetAmaclRownerId(const OicUuid_t* newROwner)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ uint8_t *cborPayload = NULL;
+ size_t size = 0;
+ OicUuid_t prevId = {.id={0}};
+
+ if(NULL == newROwner)
+ {
+ ret = OC_STACK_INVALID_PARAM;
+ }
+ if(NULL == gAmacl)
+ {
+ ret = OC_STACK_NO_RESOURCE;
+ }
+
+ if(newROwner && gAmacl)
+ {
+ memcpy(prevId.id, gAmacl->rownerID.id, sizeof(prevId.id));
+ memcpy(gAmacl->rownerID.id, newROwner->id, sizeof(newROwner->id));
+
+ ret = AmaclToCBORPayload(gAmacl, &cborPayload, &size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ ret = UpdateSecureResourceInPS(OIC_JSON_AMACL_NAME, cborPayload, size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ OICFree(cborPayload);
+ }
+
+ return ret;
+
+exit:
+ OICFree(cborPayload);
+ memcpy(gAmacl->rownerID.id, prevId.id, sizeof(prevId.id));
+ return ret;
+}
+
+OCStackResult GetAmaclRownerId(OicUuid_t *rowneruuid)
+{
+ OCStackResult retVal = OC_STACK_ERROR;
+ if (gAmacl)
+ {
+ *rowneruuid = gAmacl->rownerID;
+ retVal = OC_STACK_OK;
+ }
+ return retVal;
+}
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <string.h>
#include "oic_malloc.h"
#include "amsmgr.h"
#include "resourcemanager.h"
#include "policyengine.h"
#include "oic_string.h"
#include "caremotehandler.h"
-#include <string.h>
#define TAG "SRM-AMSMGR"
-
//Callback for AMS service multicast discovery request.
static OCStackApplicationResult AmsMgrDiscoveryCallback(void *ctx, OCDoHandle handle,
OCClientResponse * clientResponse);
static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handle,
OCClientResponse * clientResponse);
-
OCStackResult DiscoverAmsService(PEContext_t *context)
{
OIC_LOG(INFO, TAG, "IN DiscoverAmsService");
const char DOXM_DEVICEID_QUERY_FMT[] = "%s?%s=%s";
char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {};
OCCallbackData cbData = {.context=NULL};
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
- uint32_t outLen = 0;
- B64Result b64Ret;
VERIFY_NON_NULL(TAG, context, ERROR);
- b64Ret = b64Encode(context->amsMgrContext->amsDeviceId.id,
- sizeof(context->amsMgrContext->amsDeviceId.id), base64Buff, sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
snprintf(uri, sizeof(uri), DOXM_DEVICEID_QUERY_FMT, OIC_RSRC_DOXM_URI,
- OIC_JSON_DEVICE_ID_NAME, base64Buff);
+ OIC_JSON_DEVICE_ID_NAME,
+ context->amsMgrContext->amsDeviceId.id);
cbData.cb = &AmsMgrDiscoveryCallback;
cbData.context = (void*)context;
return ret;
}
-
static OCStackApplicationResult AmsMgrDiscoveryCallback(void *ctx, OCDoHandle handle,
OCClientResponse * clientResponse)
{
}
OicSecDoxm_t *doxm = NULL;
+
OIC_LOG_V(INFO, TAG, "Doxm DeviceId Discovery response = %s\n",
((OCSecurityPayload*)clientResponse->payload)->securityData);
- doxm = JSONToDoxmBin(((OCSecurityPayload*)clientResponse->payload)->securityData);
+ uint8_t *payload = ((OCSecurityPayload*)clientResponse->payload)->securityData;
+ size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
//As doxm is NULL amsmgr can't test if response from trusted AMS service
//so keep the transaction.
- if(NULL == doxm)
+ if (OC_STACK_OK == CBORPayloadToDoxm(payload, size, &doxm))
{
- OIC_LOG_V(ERROR, TAG, "%s : Unable to convert JSON to Binary",__func__);
+ OIC_LOG_V(ERROR, TAG, "%s : Unable to convert CBOR to Binary",__func__);
return OC_STACK_KEEP_TRANSACTION;
}
{
OIC_LOG(INFO, TAG, "AMS Manager Sending unicast discovery to get secured port info");
//Sending Unicast discovery to get secure port information
- if(OC_STACK_OK == SendUnicastSecurePortDiscovery(context, &clientResponse->devAddr,
+ if (OC_STACK_OK == SendUnicastSecurePortDiscovery(context, &clientResponse->devAddr,
clientResponse->connType))
{
context->retVal = ACCESS_WAITING_FOR_AMS;
return OC_STACK_DELETE_TRANSACTION;
}
-
OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,OCDevAddr *devAddr,
OCConnectivityType connType)
{
return OC_STACK_DELETE_TRANSACTION;
}
- OCResourcePayload* resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
+ OCResourcePayload *resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
//Verifying if the ID of the sender is an AMS service that this device trusts.
if(resPayload &&
return OC_STACK_DELETE_TRANSACTION;
}
-
OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType,
uint16_t securedPort)
{
OCCallbackData cbData = {.context=NULL};
OCDevAddr destAddr = {.adapter = OC_ADAPTER_IP};
B64Result b64Ret;
+ char *subID = NULL;
VERIFY_NON_NULL(TAG, context, ERROR);
VERIFY_NON_NULL(TAG, devAddr, ERROR);
- b64Ret = b64Encode(context->subject.id, sizeof(context->subject.id),
- base64Buff, sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
+ ret = ConvertUuidToStr(&context->subject, &subID);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "SendAclReq : Failed to canonical UUID encoding");
+ return OC_STACK_ERROR;
+ }
snprintf(uri, sizeof(uri), GET_ACE_QUERY_FMT, OIC_RSRC_ACL_URI,
- OIC_JSON_SUBJECT_NAME, base64Buff,
+ OIC_JSON_SUBJECTID_NAME, subID,
OIC_JSON_RESOURCES_NAME, context->resource);
+ OICFree(subID);
cbData.cb = &AmsMgrAclReqCallback;
cbData.context = context;
return ret;
}
-
static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handle,
OCClientResponse * clientResponse)
{
memcmp(context->amsMgrContext->amsDeviceId.id, clientResponse->identity.id,
sizeof(context->amsMgrContext->amsDeviceId.id)) == 0)
{
+ size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
OCStackResult ret =
- InstallNewACL(((OCSecurityPayload*)clientResponse->payload)->securityData);
+ InstallNewACL(((OCSecurityPayload*)clientResponse->payload)->securityData, size);
VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
OIC_LOG_V(INFO, TAG, "%s : Calling checkPermission", __func__);
return OC_STACK_DELETE_TRANSACTION;
}
-
OCStackResult UpdateAmsMgrContext(PEContext_t *context, const CAEndpoint_t *endpoint,
const CARequestInfo_t *requestInfo)
{
//The AmsMgr context endpoint and requestInfo will be free from ,
//AmsMgrAclReqCallback function
- if(context->amsMgrContext->endpoint)
+ if (context->amsMgrContext->endpoint)
{
OICFree(context->amsMgrContext->endpoint);
context->amsMgrContext->endpoint = NULL;
VERIFY_NON_NULL(TAG, context->amsMgrContext->endpoint, ERROR);
*context->amsMgrContext->endpoint = *endpoint;
- if(context->amsMgrContext->requestInfo)
+ if (context->amsMgrContext->requestInfo)
{
FreeCARequestInfo(context->amsMgrContext->requestInfo);
context->amsMgrContext->requestInfo = NULL;
memset(&context->amsMgrContext->amsDeviceId, 0, sizeof(context->amsMgrContext->amsDeviceId));
//Call amacl resource function to get the AMS service deviceID for the resource
- if(OC_STACK_OK == AmaclGetAmsDeviceId(context->resource, &context->amsMgrContext->amsDeviceId))
+ if (OC_STACK_OK == AmaclGetAmsDeviceId(context->resource, &context->amsMgrContext->amsDeviceId))
{
OIC_LOG_V(INFO, TAG, "%s:AMACL found for the requested resource %s",
__func__, context->resource);
return ret;
}
-
void ProcessAMSRequest(PEContext_t *context)
{
OicUuid_t emptyUuid = {.id={}};
OIC_LOG_V(INFO, TAG, "Entering %s", __func__);
- if(NULL != context)
+ if (NULL != context)
{
if((false == context->matchingAclFound) && (false == context->amsProcessing))
{
-/******************************************************************
- *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "base64.h"
-/**< base character of Base64 */
+/** base character of Base64. */
static const char g_b64TransTbl[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"\
"ghijklmnopqrstuvwxyz0123456789+/";
/**
- * base64 block encode function
+ * base64 block encode function.
*
- * @param[in] in octet stream, max 3 byte
- * @param[out] out base64 encoded stream, 4 byte
- * @param[in] len byte-length of in
+ * @param in is the octet stream, max 3 byte.
+ * @param out is the Base64 encoded stream, 4 byte.
+ * @param len is the byte-length of octet stream.
*
- * @return B64_OK for Success, otherwise some error value
+ * @return ::B64_OK for Success, otherwise some error value.
*/
static B64Result b64EncodeBlk(const uint8_t* in, char* out, uint32_t len)
{
out[0] = g_b64TransTbl[in[0] >> 2];
- if(1 == len)
+ if (1 == len)
{
out[1] = g_b64TransTbl[((in[0] & 0x03) << 4)];
}
out[1] = g_b64TransTbl[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)];
}
- if(2 == len)
+ if (2 == len)
{
out[2] = g_b64TransTbl[((in[1] & 0x0f) << 2)];
}
return B64_OK;
}
-/**
- * Encode the plain message in base64.
- *
- * @param[in] in Plain message
- * @param[in] inLen Byte length of 'in'
- * @param[in,out] outBuf Output buffer
- * Base64 encoded message will be written into 'out'
- * NOTE : This method adds a NULL to the string configuration
- * @param[in] outBufSize Size of output buffer
- * @param[out] outLen Byte length of encoded message
- *
- * @return B64_OK for Success, otherwise some error value
-*/
B64Result b64Encode(const uint8_t* in, const size_t inLen,
char* outBuf, const size_t outBufSize, uint32_t* outLen)
{
- size_t i;
- size_t minBufSize;
-
if (NULL == in || 0 == inLen || NULL == outBuf || NULL == outLen )
{
return B64_INVALID_PARAM;
*outLen = ((inLen / 3) * 3 == inLen) ?
((inLen / 3) * 4) :
(((inLen / 3) + 1) * 4);
- minBufSize = (*outLen + 1);
- if(outBufSize < minBufSize)
+ uint32_t minBufSize = (*outLen + 1);
+ if (outBufSize < minBufSize)
{
return B64_OUTPUT_BUFFER_TOO_SMALL;
}
+ uint32_t i;
for (i = 0; i < inLen / 3; i++)
{
if(B64_OK != b64EncodeBlk(in + i * 3, outBuf + i * 4, 3))
}
}
- if (i * 3 != inLen)
+ if (((size_t)i * 3) != inLen)
{
- if(B64_OK != b64EncodeBlk(in + i * 3, outBuf + i * 4, inLen - i * 3))
+ if (B64_OK != b64EncodeBlk(in + i * 3, outBuf + i * 4, inLen - i * 3))
{
return B64_INVALID_PARAM;
}
}
/**
- * Get decoded value
+ * Get decoded value.
*
- * @param[in] c Base64 encoded charactor
+ * @param c is the Base64 encoded character.
*
- * @return decoded value, 6-bit
+ * @return decoded value, 6-bit.
*/
static uint32_t b64GetVal(char c)
{
}
/**
- * base64 block decode function
+ * Base64 block decode function.
*
- * @param[in] in Base64 encoded stream, 4 bytes
- * @param[out] out Octet stream, 3 bytes
+ * @param in is the Base64 encoded stream, 4 bytes.
+ * @param out is the Octet stream, 3 bytes.
*
- * @return B64_OK for Success, otherwise some error value
+ * @return ::B64_OK for Success, otherwise some error value.
*/
static B64Result b64DecodeBlk(const char* in, uint8_t* out)
{
- uint32_t val;
-
- if(NULL == in || NULL == out)
+ if (NULL == in || NULL == out)
{
return B64_INVALID_PARAM;
}
- val = (b64GetVal(in[0]) << 18) | (b64GetVal(in[1]) << 12) |
+ uint32_t val = (b64GetVal(in[0]) << 18) | (b64GetVal(in[1]) << 12) |
(b64GetVal(in[2]) << 6) | (b64GetVal(in[3]));
out[0] = (val >> 16) & 0xff;
return B64_OK;
}
-/**
- * Decode the encoded message in base64.
- *
- * @param[in] in Base64 encoded message
- * @param[in] inLen Byte lenth of 'in'
- * @param[in, out] outBuf Output buffer
- * Base64 decoded message will be written into 'out'
- * @param[in] outBufSize Size of output buffer
- * @param[out] outLen Byte length of decoded message
- *
- * @return B64_OK for Success, otherwise some error value
- */
B64Result b64Decode(const char* in, const size_t inLen,
uint8_t* outBuf, size_t outBufSize, uint32_t* outLen)
{
- uint32_t i;
- uint32_t minBufSize;
-
if (NULL == in || 0 == inLen || 0 != (inLen & 0x03) || NULL == outBuf || NULL == outLen)
{
return B64_INVALID_PARAM;
}
*outLen = (inLen / 4) * 3;
- minBufSize = (inLen / 4) * 3;
- if('=' == in[inLen - 1])
+ uint32_t minBufSize = (inLen / 4) * 3;
+ if ('=' == in[inLen - 1])
{
minBufSize--;
(*outLen)--;
}
- if('=' == in[inLen - 2])
+ if ('=' == in[inLen - 2])
{
minBufSize--;
(*outLen)--;
}
- if(outBufSize < minBufSize)
+ if (outBufSize < minBufSize)
{
return B64_OUTPUT_BUFFER_TOO_SMALL;
}
- for (i = 0; i < inLen / 4; i++)
+ for (uint32_t i = 0; i < inLen / 4; i++)
{
if(B64_OK != b64DecodeBlk(in + i * 4, outBuf + i * 3))
{
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#define __STDC_LIMIT_MACROS
+
+#include <stdlib.h>
+#ifdef WITH_ARDUINO
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+#include <stdint.h>
+
+#include "cainterface.h"
+#include "payload_logging.h"
#include "ocstack.h"
-#include "logger.h"
+#include "ocrandom.h"
+#include "base64.h"
+#include "ocserverrequest.h"
#include "oic_malloc.h"
-#include "cJSON.h"
-#include "resourcemanager.h"
-#include "psinterface.h"
+#include "ocpayload.h"
#include "utlist.h"
-#include "srmresourcestrings.h"
#include "credresource.h"
-#include "ocrandom.h"
#include "doxmresource.h"
-#include "base64.h"
-#include "srmutility.h"
-#include "cainterface.h"
-#include "pbkdf2.h"
-#include <stdlib.h>
+#include "pstatresource.h"
#include "iotvticalendar.h"
-#include "ocserverrequest.h"
+#include "pbkdf2.h"
+#include "resourcemanager.h"
+#include "srmresourcestrings.h"
+#include "srmutility.h"
+#include "psinterface.h"
+#include "pinoxmcommon.h"
#ifdef __WITH_DTLS__
#include "global.h"
-#endif //__WITH_DTLS__
-
-#ifdef WITH_ARDUINO
-#include <string.h>
-#else
-#include <strings.h>
#endif
-#include <stdint.h>
#define TAG "SRM-CREDL"
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching belox max cbor size. */
+static const uint16_t CBOR_SIZE = 2048;
+
+/** Max cbor size payload. */
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+/** CRED size - Number of mandatory items. */
+static const uint8_t CRED_ROOT_MAP_SIZE = 2;
+static const uint8_t CRED_MAP_SIZE = 3;
+
static OicSecCred_t *gCred = NULL;
static OCResourceHandle gCredHandle = NULL;
{
if(NULL == cred)
{
- OIC_LOG (ERROR, TAG, "Invalid Parameter");
+ OIC_LOG(ERROR, TAG, "Invalid Parameter");
return;
}
//Note: Need further clarification on roleID data type
#endif
//Clean PublicData
+#ifdef __WITH_X509__
OICFree(cred->publicData.data);
+#endif
//Clean PrivateData
OICFree(cred->privateData.data);
//Clean Period
OICFree(cred->period);
- //Clean Owners
- OICFree(cred->owners);
-
//Clean Cred node itself
OICFree(cred);
}
}
}
-/**
- * This function converts credential data into JSON format.
- * Caller needs to invoke 'free' when done using
- * returned string.
- * @param cred pointer to instance of OicSecCred_t structure.
- *
- * @retval
- * pointer to JSON credential representation - if credential for subjectId found
- * NULL - if credential for subjectId not found
- */
-char * BinToCredJSON(const OicSecCred_t * cred)
+static size_t OicSecCredCount(const OicSecCred_t *secCred)
{
- cJSON *jsonRoot = NULL;
- char *jsonStr = NULL;
+ size_t size = 0;
+ for (const OicSecCred_t *cred = secCred; cred; cred = cred->next)
+ {
+ size++;
+ }
+ return size;
+}
- if (cred)
+OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
+ size_t *cborSize)
+{
+ if (NULL == credS || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
{
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
+ return OC_STACK_INVALID_PARAM;
+ }
- jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ OCStackResult ret = OC_STACK_ERROR;
- cJSON *jsonCredArray = NULL;
- cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRED_NAME,
- jsonCredArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonCredArray, ERROR);
+ CborError cborEncoderResult = CborNoError;
+ uint8_t *outPayload = NULL;
+ size_t cborLen = *cborSize;
+ *cborSize = 0;
+ *cborPayload = NULL;
+ const OicSecCred_t *cred = credS;
+ CborEncoder encoder;
+ CborEncoder credArray;
+ CborEncoder credRootMap;
+
+ if (0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
+ }
- while(cred)
- {
- cJSON *jsonCred = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonCred, ERROR);
+ outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
- //CredID -- Mandatory
- cJSON_AddNumberToObject(jsonCred, OIC_JSON_CREDID_NAME, (int)cred->credId);
+ // Create CRED Root Map (creds, rownerid)
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &credRootMap, CRED_ROOT_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Root Map");
- //Subject -- Mandatory
- outLen = 0;
- memset(base64Buff, 0, sizeof(base64Buff));
- b64Ret = b64Encode(cred->subject.id, sizeof(cred->subject.id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonCred, OIC_JSON_SUBJECT_NAME, base64Buff);
+ // creds
+ cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_CREDS_NAME,
+ strlen(OIC_JSON_CREDS_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding creds Name Tag.");
- //Note: Need further clarification on roleID data type
-#if 0
- //RoleId -- Not Mandatory
- if(cred->roleIdsLen > 0)
- {
- cJSON *jsonRoleIdsArray = NULL;
- cJSON_AddItemToObject (jsonCred, OIC_JSON_ROLEIDS_NAME,
- jsonRoleIdsArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonRoleIdsArray, ERROR);
- for (size_t i = 0; i < cred->roleIdsLen; i++)
- {
- cJSON_AddItemToArray (jsonRoleIdsArray,
- cJSON_CreateString((char *)cred->roleIds[i].id));
- }
- }
-#endif
+ // creds array
+ cborEncoderResult = cbor_encoder_create_array(&credRootMap, &credArray, OicSecCredCount(cred));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Array.");
- //CredType -- Mandatory
- cJSON_AddNumberToObject(jsonCred, OIC_JSON_CREDTYPE_NAME,(int)cred->credType);
+ while (cred)
+ {
+ CborEncoder credMap;
+ size_t mapSize = CRED_MAP_SIZE;
+ char *subject = NULL;
+ if (cred->period)
+ {
+ mapSize++;
+ }
+#ifdef __WITH_X509__
+ if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
+ {
+ mapSize++;
+ }
+#endif /* __WITH_X509__ */
+ if (cred->privateData.data)
+ {
+ mapSize++;
+ }
+ cborEncoderResult = cbor_encoder_create_map(&credArray, &credMap, mapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Map");
+
+ //CredID -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDID_NAME,
+ strlen(OIC_JSON_CREDID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Tag. ");
+ cborEncoderResult = cbor_encode_int(&credMap, cred->credId);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Id Value.");
+
+ //Subject -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
+ strlen(OIC_JSON_SUBJECTID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
+ ret = ConvertUuidToStr(&cred->subject, &subject);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&credMap, subject, strlen(subject));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Subject Id Value.");
+ OICFree(subject);
+
+ //CredType -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_CREDTYPE_NAME,
+ strlen(OIC_JSON_CREDTYPE_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag.");
+ cborEncoderResult = cbor_encode_int(&credMap, cred->credType);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
#ifdef __WITH_X509__
- //PublicData -- Not Mandatory
- if(cred->publicData.data)
- {
- if (SIGNED_ASYMMETRIC_KEY == cred->credType)
- {
- cJSON_AddItemToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME,
- cJSON_Parse(cred->publicData.data));
- }
- else
- {
- cJSON_AddStringToObject(jsonCred, OIC_JSON_PUBLICDATA_NAME, cred->publicData.data);
- }
- }
+ //PublicData -- Not Mandatory
+ if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
+ {
+ CborEncoder publicMap;
+ const size_t publicMapSize = 2;
+
+ cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
+ strlen(OIC_JSON_PUBLICDATA_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
+
+ cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
+
+ cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
+ strlen(OIC_JSON_DATA_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
+ cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
+ cred->publicData.len);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
+
+ // TODO: Need to data strucure modification for OicSecCert_t.
+ cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
+ strlen(OIC_JSON_ENCODING_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
+ cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_RAW,
+ strlen(OIC_SEC_ENCODING_RAW));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
+
+ cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
+ }
#endif /*__WITH_X509__*/
- //PrivateData -- Not Mandatory
- if(cred->privateData.data)
- {
-#ifdef __WITH_X509__
- if (SIGNED_ASYMMETRIC_KEY == cred->credType)
- {
- cJSON_AddItemToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME,
- cJSON_Parse(cred->privateData.data));
- }
- else
- {
- cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data);
- }
-#else
- cJSON_AddStringToObject(jsonCred, OIC_JSON_PRIVATEDATA_NAME, cred->privateData.data);
-#endif
- }
+ //PrivateData -- Not Mandatory
+ if(cred->privateData.data)
+ {
+ CborEncoder privateMap;
+ const size_t privateMapSize = 2;
+
+ cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
+ strlen(OIC_JSON_PRIVATEDATA_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
+
+ cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
+
+ cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
+ strlen(OIC_JSON_DATA_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
+ cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
+ cred->privateData.len);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
+
+ // TODO: Need to data strucure modification for OicSecKey_t.
+ cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
+ strlen(OIC_JSON_ENCODING_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
+ cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
+ strlen(OIC_SEC_ENCODING_RAW));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
+
+ cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
+ }
- //Period -- Not Mandatory
- if(cred->period)
- {
- cJSON_AddStringToObject(jsonCred, OIC_JSON_PERIOD_NAME,
- cred->period);
- }
+ //Period -- Not Mandatory
+ if(cred->period)
+ {
+ cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PERIOD_NAME,
+ strlen(OIC_JSON_PERIOD_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Tag.");
+ cborEncoderResult = cbor_encode_text_string(&credMap, cred->period,
+ strlen(cred->period));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
+ }
- //Owners -- Mandatory
- cJSON *jsonOwnrArray = NULL;
- cJSON_AddItemToObject (jsonCred, OIC_JSON_OWNERS_NAME,
- jsonOwnrArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
- for (size_t i = 0; i < cred->ownersLen; i++)
- {
- outLen = 0;
- memset(base64Buff, 0, sizeof(base64Buff));
- b64Ret = b64Encode(cred->owners[i].id, sizeof(cred->owners[i].id),
- base64Buff, sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddItemToArray (jsonOwnrArray,
- cJSON_CreateString((char *)(base64Buff)));
- }
- /* Attach current cred node to cred Array */
- cJSON_AddItemToArray(jsonCredArray, jsonCred);
- cred = cred->next;
- }
+ cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
- jsonStr = cJSON_PrintUnformatted(jsonRoot);
+ cred = cred->next;
}
+ cborEncoderResult = cbor_encoder_close_container(&credRootMap, &credArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Array.");
-exit:
- if (jsonRoot)
+ cred = credS;
+
+ // Rownerid
{
- cJSON_Delete(jsonRoot);
+ char *rowner = NULL;
+ cborEncoderResult = cbor_encode_text_string(&credRootMap, OIC_JSON_ROWNERID_NAME,
+ strlen(OIC_JSON_ROWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding rownerid Name.");
+ ret = ConvertUuidToStr(&cred->rownerID, &rowner);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&credRootMap, rowner, strlen(rowner));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding rownerid Value.");
+ OICFree(rowner);
}
- return jsonStr;
-}
-/*
- * This internal method converts JSON cred into binary cred.
- */
-OicSecCred_t * JSONToCredBin(const char * jsonStr)
-{
- OCStackResult ret = OC_STACK_ERROR;
- OicSecCred_t * headCred = NULL;
- OicSecCred_t * prevCred = NULL;
- cJSON *jsonCredArray = NULL;
+ // Close CRED Root Map
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &credRootMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing CRED Root Map.");
- cJSON *jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ if (CborNoError == cborEncoderResult)
+ {
+ OIC_LOG(DEBUG, TAG, "CredToCBORPayload Successed");
+ *cborPayload = outPayload;
+ *cborSize = encoder.ptr - outPayload;
+ ret = OC_STACK_OK;
+ }
+ OIC_LOG(DEBUG, TAG, "CredToCBORPayload OUT");
+exit:
+ if (CborErrorOutOfMemory == cborEncoderResult)
+ {
+ OIC_LOG(DEBUG, TAG, "CredToCBORPayload:CborErrorOutOfMemory : retry with more memory");
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = CredToCBORPayload(credS, cborPayload, &cborLen);
+ *cborSize = cborLen;
+ }
- jsonCredArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME);
- VERIFY_NON_NULL(TAG, jsonCredArray, ERROR);
- if (cJSON_Array == jsonCredArray->type)
+ if (CborNoError != cborEncoderResult)
{
- int numCred = cJSON_GetArraySize(jsonCredArray);
- int idx = 0;
+ OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
+ OICFree(outPayload);
+ outPayload = NULL;
+ *cborSize = 0;
+ *cborPayload = NULL;
+ ret = OC_STACK_ERROR;
+ }
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
+ return ret;
+}
- VERIFY_SUCCESS(TAG, numCred > 0, ERROR);
- do
- {
- cJSON *jsonCred = cJSON_GetArrayItem(jsonCredArray, idx);
- VERIFY_NON_NULL(TAG, jsonCred, ERROR);
+OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
+ OicSecCred_t **secCred)
+{
+ if (NULL == cborPayload || NULL == secCred || NULL != *secCred || 0 == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
- OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
- VERIFY_NON_NULL(TAG, cred, ERROR);
+ OCStackResult ret = OC_STACK_ERROR;
+ CborValue credCbor = { .parser = NULL };
+ CborParser parser = { .end = NULL };
+ CborError cborFindResult = CborNoError;
+ cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
- headCred = (headCred) ? headCred : cred;
- if (prevCred)
- {
- prevCred->next = cred;
- }
- size_t jsonObjLen = 0;
- cJSON *jsonObj = NULL;
+ OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
- //CredId -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDID_NAME);
- if(jsonObj)
- {
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- cred->credId = jsonObj->valueint;
- }
+ // Enter CRED Root Map
+ CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+ cborFindResult = cbor_value_enter_container(&credCbor, &CredRootMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering CRED Root Map.");
- //subject -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_SUBJECT_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- outLen = 0;
- memset(base64Buff, 0, sizeof(base64Buff));
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring),
- base64Buff, sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(cred->subject.id)),
- ERROR);
- memcpy(cred->subject.id, base64Buff, outLen);
-
- //CredType -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDTYPE_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- cred->credType = (OicSecCredType_t)jsonObj->valueint;
-
- //PrivateData is mandatory for some of the credential types listed below.
- jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PRIVATEDATA_NAME);
- if ((cred->credType & SYMMETRIC_PAIR_WISE_KEY) ||
- (cred->credType & SYMMETRIC_GROUP_KEY) ||
- (cred->credType & PIN_PASSWORD))
- {
- if(jsonObj)
- {
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- }
- }
-#ifdef __WITH_X509__
- else if (cred->credType & SIGNED_ASYMMETRIC_KEY)
- {
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR);
- }
-#endif // __WITH_X509__
- if (NULL != jsonObj)
+ while (cbor_value_is_valid(&CredRootMap))
+ {
+ char* tagName = NULL;
+ size_t len = 0;
+ CborType type = cbor_value_get_type(&CredRootMap);
+ if (type == CborTextStringType)
+ {
+ cborFindResult = cbor_value_dup_text_string(&CredRootMap, &tagName, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Root Map.");
+ cborFindResult = cbor_value_advance(&CredRootMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Root Map.");
+ }
+ if(tagName)
+ {
+ if (strcmp(tagName, OIC_JSON_CREDS_NAME) == 0)
{
- if (cJSON_String == jsonObj->type)
+ // Enter CREDS Array
+ size_t len = 0;
+ int credCount = 0;
+ CborValue credArray = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+ cborFindResult = cbor_value_enter_container(&CredRootMap, &credArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Array.");
+
+ while (cbor_value_is_valid(&credArray))
{
- jsonObjLen = strlen(jsonObj->valuestring) + 1;
- cred->privateData.data = (char *)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
- strncpy((char *)cred->privateData.data, (char *)jsonObj->valuestring, jsonObjLen);
- }
-#ifdef __WITH_X509__
- else if (SIGNED_ASYMMETRIC_KEY == cred->credType && cJSON_Object == jsonObj->type)
- {
- cred->privateData.data = cJSON_PrintUnformatted(jsonObj);
- VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
- }
-#endif // __WITH_X509__
- }
- else
- {
- cred->privateData.data = NULL;
- }
+ credCount++;
+ //CredId -- Mandatory
+ CborValue credMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+ cborFindResult = cbor_value_enter_container(&credArray, &credMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Cred Map.");
+ OicSecCred_t *cred = NULL;
+
+ if(1 == credCount)
+ {
+ cred = headCred;
+ }
+ else
+ {
+ cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
+ OicSecCred_t *temp = headCred;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = cred;
+ }
- //PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type.
- jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PUBLICDATA_NAME);
-#ifdef __WITH_X509__
- if (cred->credType & SIGNED_ASYMMETRIC_KEY)
- {
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Object == jsonObj->type, ERROR);
- }
-#endif // __WITH_X509__
- if (NULL != jsonObj)
- {
- if (cJSON_String == jsonObj->type)
- {
- jsonObjLen = strlen(jsonObj->valuestring) + 1;
- cred->publicData.data = (char *)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR);
- strncpy((char *)cred->publicData.data, (char *)jsonObj->valuestring, jsonObjLen);
- }
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+
+ while(cbor_value_is_valid(&credMap))
+ {
+ char* name = NULL;
+ CborType type = cbor_value_get_type(&credMap);
+ if (type == CborTextStringType)
+ {
+ cborFindResult = cbor_value_dup_text_string(&credMap, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Name in CRED Map.");
+ cborFindResult = cbor_value_advance(&credMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Value in CRED Map.");
+ }
+ if(name)
+ {
+ //credid
+ if (strcmp(name, OIC_JSON_CREDID_NAME) == 0)
+ {
+ cborFindResult = cbor_value_get_uint64(&credMap, (uint64_t *) &cred->credId);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredId.");
+ }
+ // subjectid
+ if (strcmp(name, OIC_JSON_SUBJECTID_NAME) == 0)
+ {
+ char *subjectid = NULL;
+ cborFindResult = cbor_value_dup_text_string(&credMap, &subjectid, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding subjectid Value.");
+ ret = ConvertStrToUuid(subjectid, &cred->subject);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(subjectid);
+ }
+ // credtype
+ if (strcmp(name, OIC_JSON_CREDTYPE_NAME) == 0)
+ {
+ cborFindResult = cbor_value_get_uint64(&credMap, (uint64_t *) &cred->credType);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
+ }
+ // privatedata
+ if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME) == 0)
+ {
+ CborValue privateMap = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
+
+ while (cbor_value_is_valid(&privateMap))
+ {
+ char* privname = NULL;
+ CborType type = cbor_value_get_type(&privateMap);
+ if (type == CborTextStringType)
+ {
+ cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
+ &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+ cborFindResult = cbor_value_advance(&privateMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+ }
+ if (privname)
+ {
+ // PrivateData::privdata -- Mandatory
+ if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
+ {
+ cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
+ &cred->privateData.len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
+ }
+ // PrivateData::encoding -- Mandatory
+ if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
+ {
+ // TODO: Need to update data structure, just ignore encoding value now.
+ }
+ }
+ if (cbor_value_is_valid(&privateMap))
+ {
+ cborFindResult = cbor_value_advance(&privateMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
+ }
+ OICFree(privname);
+ }
+
+ }
#ifdef __WITH_X509__
- else if (SIGNED_ASYMMETRIC_KEY == cred->credType && cJSON_Object == jsonObj->type)
- {
- cred->publicData.data = cJSON_PrintUnformatted(jsonObj);
- VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR);
+ if (strcmp(name, OIC_JSON_PUBLICDATA_NAME) == 0)
+ {
+ CborValue pubMap = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
+
+ while (cbor_value_is_valid(&pubMap))
+ {
+ char* pubname = NULL;
+ CborType type = cbor_value_get_type(&pubMap);
+ if (type == CborTextStringType)
+ {
+ cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
+ &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+ cborFindResult = cbor_value_advance(&pubMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+ }
+ if (pubname)
+ {
+ // PrivateData::privdata -- Mandatory
+ if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0)
+ {
+ cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
+ &cred->publicData.len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
+ }
+ // PublicData::encoding -- Mandatory
+ if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
+ {
+ // TODO: Need to update data structure, just ignore encoding value now.
+ }
+ }
+ if (cbor_value_is_valid(&pubMap))
+ {
+ cborFindResult = cbor_value_advance(&pubMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
+ }
+ OICFree(pubname);
+ }
+ }
+#endif //__WITH_X509__
+
+ if (0 == strcmp(OIC_JSON_PERIOD_NAME, name))
+ {
+ cborFindResult = cbor_value_dup_text_string(&credMap, &cred->period, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
+ }
+
+ if (cbor_value_is_valid(&credMap))
+ {
+ cborFindResult = cbor_value_advance(&credMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Map.");
+ }
+ OICFree(name);
+ }
+ }
+ cred->next = NULL;
+ if (cbor_value_is_valid(&credArray))
+ {
+ cborFindResult = cbor_value_advance(&credArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Array.");
+ }
}
-#endif // __WITH_X509__
}
- //Period -- Not Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PERIOD_NAME);
- if(jsonObj && cJSON_String == jsonObj->type)
+ //ROwner -- Mandatory
+ if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0)
{
- jsonObjLen = strlen(jsonObj->valuestring) + 1;
- cred->period = (char *)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, cred->period, ERROR);
- strncpy(cred->period, jsonObj->valuestring, jsonObjLen);
- }
+ char *stRowner = NULL;
+ cborFindResult = cbor_value_dup_text_string(&CredRootMap, &stRowner, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Rownerid Value.");
- //Owners -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_OWNERS_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
- cred->ownersLen = (size_t)cJSON_GetArraySize(jsonObj);
- VERIFY_SUCCESS(TAG, cred->ownersLen > 0, ERROR);
- cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, (cred->owners), ERROR);
- for(size_t i = 0; i < cred->ownersLen; i++)
- {
- cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, i);
- VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
- outLen = 0;
- memset(base64Buff, 0, sizeof(base64Buff));
- b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring),
- base64Buff, sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK &&
- outLen <= sizeof(cred->owners[i].id)), ERROR);
- memcpy(cred->owners[i].id, base64Buff, outLen);
+ ret = ConvertStrToUuid(stRowner, &headCred->rownerID);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(stRowner);
}
- prevCred = cred;
- } while( ++idx < numCred);
+ OICFree(tagName);
+ }
+ if (cbor_value_is_valid(&CredRootMap))
+ {
+ cborFindResult = cbor_value_advance(&CredRootMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing CRED Root Map.");
+ }
}
+ *secCred = headCred;
ret = OC_STACK_OK;
exit:
- cJSON_Delete(jsonRoot);
- if (OC_STACK_OK != ret)
+ if (CborNoError != cborFindResult)
{
DeleteCredList(headCred);
headCred = NULL;
+ *secCred = NULL;
+ ret = OC_STACK_ERROR;
}
- return headCred;
+
+ return ret;
}
-/**
- * This function generates the bin credential data.
- *
- * @param subject pointer to subject of this credential.
- * @param credType credential type.
- * @param publicData public data such as public key.
- * @param privateData private data such as private key.
- * The privateData is expected in base64 encoded format.
- * @param ownersLen length of owners array
- * @param owners array of owners.
- *
- * @retval
- * pointer to instance of OicSecCred_t - success
- * NULL - error
- */
OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
- const char * publicData, const char * privateData,
- size_t ownersLen, const OicUuid_t * owners)
+ const OicSecCert_t * publicData, const OicSecKey_t* privateData,
+ const OicUuid_t * rownerID)
{
(void)publicData;
OCStackResult ret = OC_STACK_ERROR;
- OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+ OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
VERIFY_NON_NULL(TAG, cred, ERROR);
//CredId is assigned before appending new cred to the existing
cred->credType = credType;
#ifdef __WITH_X509__
- if(publicData)
+ if (publicData && publicData->data)
{
- cred->publicData.data = (char *)OICMalloc(strlen(publicData)+1);
+ cred->publicData.data = (uint8_t *)OICCalloc(1, publicData->len);
VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
- strncpy((char *)cred->publicData.data, publicData, strlen(publicData)+1);
+ memcpy(cred->publicData.data, publicData->data, publicData->len);
+ cred->publicData.len = publicData->len;
}
#endif // __WITH_X509__
- if(privateData)
+ if (privateData && privateData->data)
{
- cred->privateData.data = (char *)OICMalloc(strlen(privateData)+1);
+ cred->privateData.data = (uint8_t *)OICCalloc(1, privateData->len);
VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
- strncpy((char *)cred->privateData.data, privateData, strlen(privateData)+1);
+ memcpy(cred->privateData.data, privateData->data, privateData->len);
+ cred->privateData.len = privateData->len;
}
- VERIFY_SUCCESS(TAG, ownersLen > 0, ERROR);
- cred->ownersLen = ownersLen;
-
- cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, cred->owners, ERROR);
- for(size_t i = 0; i < cred->ownersLen; i++)
- {
- memcpy(cred->owners[i].id, owners[i].id, sizeof(cred->owners[i].id));
- }
+ VERIFY_NON_NULL(TAG, rownerID, ERROR);
+ memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
ret = OC_STACK_OK;
exit:
bool ret = false;
// Convert Cred data into JSON for update to persistent storage
- char *jsonStr = BinToCredJSON(cred);
- if (jsonStr)
+ if (cred)
{
- cJSON *jsonCred = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- if ((jsonCred) &&
- (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRED_NAME, jsonCred)))
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ OCStackResult res = CredToCBORPayload(cred, &payload, &size);
+ if ((OC_STACK_OK == res) && payload)
{
- ret = true;
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, payload, size))
+ {
+ ret = true;
+ }
+ OICFree(payload);
}
- cJSON_Delete(jsonCred );
}
else //Empty cred list
{
- if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRED_NAME, NULL))
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, NULL, 0))
{
ret = true;
}
}
/**
- * Compare function used LL_SORT for sorting credentials
+ * Compare function used LL_SORT for sorting credentials.
*
- * @param first pointer to OicSecCred_t struct
- * @param second pointer to OicSecCred_t struct
+ * @param first pointer to OicSecCred_t struct.
+ * @param second pointer to OicSecCred_t struct.
*
- *@retval
- * -1 if credId of first is less than credId of second
- * 0 if credId of first is equal to credId of second
- * 1 if credId of first is greater than credId of second
+ *@return -1, if credId of first is less than credId of second.
+ * 0, if credId of first is equal to credId of second.
+ * 1, if credId of first is greater than credId of second.
*/
static int CmpCredId(const OicSecCred_t * first, const OicSecCred_t *second)
{
- if(first->credId < second->credId)
+ if (first->credId < second->credId)
{
return -1;
}
- else if(first->credId > second->credId)
+ else if (first->credId > second->credId)
{
return 1;
}
* available due deletion of OicSecCred_t object or one more than
* credId of last credential in the list.
*
- * @retval
- * next available credId - success
- * 0 - error
+ * @return next available credId if successful, else 0 for error.
*/
-
static uint16_t GetCredId()
{
//Sorts credential list in incremental order of credId
LL_SORT(gCred, CmpCredId);
-
OicSecCred_t *currentCred = NULL, *credTmp = NULL;
uint16_t nextCredId = 1;
LL_FOREACH_SAFE(gCred, currentCred, credTmp)
{
- if(currentCred->credId == nextCredId)
+ if (currentCred->credId == nextCredId)
{
nextCredId += 1;
}
}
/**
- * Get the default value
- * @retval NULL for now. Update it when we finalize the default info.
+ * Get the default value.
+ *
+ * @return NULL for now.
*/
static OicSecCred_t* GetCredDefault()
{
+ // TODO:Update it when we finalize the default info.
return NULL;
}
-/**
- * This function adds the new cred to the credential list.
- *
- * @param cred pointer to new credential.
- *
- * @retval
- * OC_STACK_OK - cred not NULL and persistent storage gets updated
- * OC_STACK_ERROR - cred is NULL or fails to update persistent storage
- */
OCStackResult AddCredential(OicSecCred_t * newCred)
{
OCStackResult ret = OC_STACK_ERROR;
-
VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
//Assigning credId to the newCred
newCred->credId = GetCredId();
-
VERIFY_SUCCESS(TAG, newCred->credId != 0, ERROR);
//Append the new Cred to existing list
LL_APPEND(gCred, newCred);
- if(UpdatePersistentStorage(gCred))
+ if (UpdatePersistentStorage(gCred))
{
ret = OC_STACK_OK;
}
LL_FOREACH_SAFE(gCred, cred, tempCred)
{
- if(memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
+ if (memcmp(cred->subject.id, subject->id, sizeof(subject->id)) == 0)
{
LL_DELETE(gCred, cred);
FreeCred(cred);
}
}
- if(deleteFlag)
+ if (deleteFlag)
{
- if(UpdatePersistentStorage(gCred))
+ if (UpdatePersistentStorage(gCred))
{
ret = OC_STACK_RESOURCE_DELETED;
}
DeleteCredList(gCred);
gCred = GetCredDefault();
- if(!UpdatePersistentStorage(gCred))
+ if (!UpdatePersistentStorage(gCred))
{
return OC_STACK_ERROR;
}
* @param ownerAdd address of OBT(PT)
* @param doxm current device's doxm resource
*
- * @retval
+ * @return
* true successfully done and valid ower psk information
* false Invalid owner psk information or failed to owner psk generation
*/
OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
//Generate owner credential based on recevied credential information
- size_t b64BufSize = B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128 * sizeof(char));
- uint8_t* encodeBuff = OICMalloc((b64BufSize + 1) * sizeof(char));
- VERIFY_NON_NULL(TAG, encodeBuff, ERROR);
- uint32_t encodedSize = 0;
- B64Result b64Ret = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128,
- (char*)encodeBuff, b64BufSize + 1, &encodedSize);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- encodeBuff[encodedSize] = '\0';
-
- //memory re-allocation for private data
- OICFree(receviedCred->privateData.data);
- receviedCred->privateData.data = (char*)OICMalloc((encodedSize + 1) * sizeof(char));
+ receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
-
- //fill the base64 encoded private data
- strncpy(receviedCred->privateData.data, (char*)encodeBuff, b64BufSize + 1);
+ receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
+ memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
- //deallocate local memory
- OICFree(encodeBuff);
-
//Verify OwnerPSK information
return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
exit:
//receviedCred->privateData.data will be deallocated when deleting credential.
- OICFree(encodeBuff);
return false;
}
static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehRequest)
{
OCEntityHandlerResult ret = OC_EH_ERROR;
-
- //Get binary representation of json
- OicSecCred_t * cred = JSONToCredBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
-
- if(cred)
+ OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest IN");
+
+ //Get binary representation of cbor
+ OicSecCred_t *cred = NULL;
+ uint8_t *payload = (((OCSecurityPayload*)ehRequest->payload)->securityData);
+ size_t size = (((OCSecurityPayload*)ehRequest->payload)->payloadSize);
+ OCStackResult res = CBORPayloadToCred(payload, size, &cred);
+ if (res == OC_STACK_OK)
{
#ifdef __WITH_DTLS__
OicUuid_t emptyUuid = {.id={0}};
#endif//__WITH_DTLS__
}
- if(OC_EH_RESOURCE_CREATED != ret)
+ if (OC_EH_RESOURCE_CREATED != ret)
{
if(OC_STACK_OK != RemoveCredential(&cred->subject))
{
}
FreeCred(cred);
}
-
+ OIC_LOG(DEBUG, TAG, "HandleCREDPutRequest OUT");
return ret;
}
{
OCEntityHandlerResult ret = OC_EH_ERROR;
- //Get binary representation of json
- OicSecCred_t * cred = JSONToCredBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
-
- if(cred)
+ //Get binary representation of CBOR
+ OicSecCred_t *cred = NULL;
+ uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
+ OCStackResult res = CBORPayloadToCred(payload, size, &cred);
+ if ((OC_STACK_OK == res) && cred)
{
//If the Post request credential has credId, it will be
//discarded and the next available credId will be assigned
OCEntityHandlerResult ehRet = OC_EH_ERROR;
- if(NULL == ehRequest->query)
- {
- return ehRet;
- }
-
- OicParseQueryIter_t parseIter = {.attrPos=NULL};
- OicUuid_t subject = {.id={0}};
-
- //Parsing REST query to get the subject
- ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
- while(GetNextQuery(&parseIter))
- {
- if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME,
- parseIter.attrLen) == 0)
- {
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
-
- b64Ret = b64Decode((char *)parseIter.valPos, parseIter.valLen,
- base64Buff, sizeof(base64Buff), &outLen);
-
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(subject.id)), ERROR);
- memcpy(subject.id, base64Buff, outLen);
- }
- }
-
- if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
- {
- ehRet = OC_EH_RESOURCE_DELETED;
- }
+ if (NULL == ehRequest->query)
+ {
+ return ehRet;
+ }
+
+ OicParseQueryIter_t parseIter = { .attrPos=NULL };
+ OicUuid_t subject = {.id={0}};
+
+ //Parsing REST query to get the subject
+ ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
+ while (GetNextQuery(&parseIter))
+ {
+ if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECTID_NAME,
+ parseIter.attrLen) == 0)
+ {
+ OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ }
+ }
+
+ if (OC_STACK_RESOURCE_DELETED == RemoveCredential(&subject))
+ {
+ ehRet = OC_EH_RESOURCE_DELETED;
+ }
exit:
return ehRet;
}
-/*
- * This internal method is the entity handler for Cred resources
- * to handle REST request (PUT/POST/DEL)
- */
-OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag,
+OCEntityHandlerResult CredEntityHandler(OCEntityHandlerFlag flag,
OCEntityHandlerRequest * ehRequest,
void* callbackParameter)
{
(void)callbackParameter;
OCEntityHandlerResult ret = OC_EH_ERROR;
- if(!ehRequest)
+ if (!ehRequest)
{
return OC_EH_ERROR;
}
{
OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
//TODO : Handle PUT/DEL methods
- switch(ehRequest->method)
+ switch (ehRequest->method)
{
case OC_REST_GET:
ret = OC_EH_FORBIDDEN;
}
//Send payload to request originator
- ret = (SendSRMResponse(ehRequest, ret, NULL) == OC_STACK_OK ?
- ret : OC_EH_ERROR);
+ ret = (SendSRMResponse(ehRequest, ret, NULL, 0) == OC_STACK_OK) ?
+ ret : OC_EH_ERROR;
return ret;
}
-/*
- * This internal method is used to create '/oic/sec/Cred' resource.
- */
OCStackResult CreateCredResource()
{
- OCStackResult ret;
-
- ret = OCCreateResource(&gCredHandle,
- OIC_RSRC_TYPE_SEC_CRED,
- OIC_MI_DEF,
- OIC_RSRC_CRED_URI,
- CredEntityHandler,
- NULL,
- OC_RES_PROP_NONE);
+ OCStackResult ret = OCCreateResource(&gCredHandle,
+ OIC_RSRC_TYPE_SEC_CRED,
+ OIC_MI_DEF,
+ OIC_RSRC_CRED_URI,
+ CredEntityHandler,
+ NULL,
+ OC_RES_PROP_NONE);
if (OC_STACK_OK != ret)
{
return ret;
}
-/**
- * Initialize Cred resource by loading data from persistent storage.
- *
- * @retval
- * OC_STACK_OK - no errors
- * OC_STACK_ERROR - stack process error
- */
OCStackResult InitCredResource()
{
OCStackResult ret = OC_STACK_ERROR;
//Read Cred resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
-
- if (jsonSVRDatabase)
+ uint8_t *data = NULL;
+ size_t size = 0;
+ ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &data, &size);
+ // If database read failed
+ if (ret != OC_STACK_OK)
+ {
+ OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
+ if (data)
{
- //Convert JSON Cred into binary format
- gCred = JSONToCredBin(jsonSVRDatabase);
+ // Read ACL resource from PS
+ ret = CBORPayloadToCred(data, size, &gCred);
}
+
/*
* If SVR database in persistent storage got corrupted or
* is not available for some reason, a default Cred is created
* which allows user to initiate Cred provisioning again.
*/
- if (!jsonSVRDatabase || !gCred)
+ if (ret != OC_STACK_OK || !data || !gCred)
{
gCred = GetCredDefault();
}
//Instantiate 'oic.sec.cred'
ret = CreateCredResource();
- OICFree(jsonSVRDatabase);
+ OICFree(data);
return ret;
}
-/**
- * Perform cleanup for Cred resources.
- *
- * @return
- * OC_STACK_OK - no errors
- * OC_STACK_ERROR - stack process error
- * OC_STACK_NO_RESOURCE - resource not found
- * OC_STACK_INVALID_PARAM - invalid param
- */
OCStackResult DeInitCredResource()
{
OCStackResult result = OCDeleteResource(gCredHandle);
return result;
}
-/**
- * This method is used by tinydtls/SRM to retrieve credential for given Subject.
- *
- * @param subject - subject for which credential is required.
- *
- * @retval
- * reference to OicSecCred_t - if credential is found
- * NULL - if credential not found
- */
const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject)
{
OicSecCred_t *cred = NULL;
#if defined(__WITH_DTLS__)
-/**
- * This internal callback is used by lower stack (i.e. CA layer) to
- * retrieve PSK credentials from RI security layer.
- *
- * @param[in] type type of PSK data required by tinyDTLS layer during DTLS handshake.
- * @param[in] desc Additional request information.
- * @param[in] desc_len The actual length of desc.
- * @param[out] result Must be filled with the requested information.
- * @param[in] result_length Maximum size of @p result.
- *
- * @return The number of bytes written to @p result or a value
- * less than zero on error.
- */
-int32_t GetDtlsPskCredentials( CADtlsPskCredType_t type,
- const unsigned char *desc, size_t desc_len,
- unsigned char *result, size_t result_length)
+int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
+ const uint8_t *desc, size_t desc_len,
+ uint8_t *result, size_t result_length)
{
int32_t ret = -1;
}
}
- // Convert PSK from Base64 encoding to binary before copying
- uint32_t outLen = 0;
- B64Result b64Ret = b64Decode(cred->privateData.data,
- strlen(cred->privateData.data), result,
- result_length, &outLen);
- if (B64_OK != b64Ret)
- {
- OIC_LOG (ERROR, TAG, "Base64 decoding failed.");
- ret = -1;
- return ret;
- }
- return outLen;
+ // Copy PSK.
+ result_length = cred->privateData.len;
+ memcpy(result, cred->privateData.data, result_length);
+ return result_length;
}
}
}
* @param[in] credType Type of credential to be added
* @param[in] pin numeric characters
* @param[in] pinSize length of 'pin'
- * @param[in] ownersLen Number of owners
- * @param[in] owners Array of owners
+ * @param[in] rownerID Resource owner's UUID
* @param[out] tmpCredSubject Generated credential's subject.
*
* @return OC_STACK_OK for success and errorcode otherwise.
*/
OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t credType,
const char * pin, size_t pinSize,
- size_t ownersLen, const OicUuid_t * owners, OicUuid_t* tmpCredSubject)
+ const OicUuid_t * rownerID, OicUuid_t* tmpCredSubject)
{
OCStackResult ret = OC_STACK_ERROR;
+ OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN IN");
if(NULL == tmpSubject || NULL == pin || 0 == pinSize || NULL == tmpCredSubject)
{
}
uint8_t privData[OWNER_PSK_LENGTH_128] = {0,};
- int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, owners->id,
+ OicSecKey_t privKey = {privData, OWNER_PSK_LENGTH_128};
+ OicSecCred_t* cred = NULL;
+ int dtlsRes = DeriveCryptoKeyFromPassword((const unsigned char *)pin, pinSize, rownerID->id,
UUID_LENGTH, PBKDF_ITERATIONS,
OWNER_PSK_LENGTH_128, privData);
VERIFY_SUCCESS(TAG, (0 == dtlsRes) , ERROR);
- uint32_t outLen = 0;
- char base64Buff[B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128) + 1] = {};
- B64Result b64Ret = b64Encode(privData, OWNER_PSK_LENGTH_128, base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (B64_OK == b64Ret), ERROR);
-
- OicSecCred_t* cred = GenerateCredential(tmpSubject, credType, NULL,
- base64Buff, ownersLen, owners);
+ cred = GenerateCredential(tmpSubject, credType, NULL,
+ &privKey, rownerID);
if(NULL == cred)
{
OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to generate credential");
RemoveCredential(tmpSubject);
OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
}
+ OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
exit:
return ret;
#define CERTIFICATE ("x5c")
#define PRIVATE_KEY ("d")
-
-static void WriteCertPrefix(uint8_t *prefix, uint32_t certLen)
-{
- for (size_t i = 0; i < CERT_LEN_PREFIX; ++i)
- {
- prefix[i] = (certLen >> (BYTE_SIZE * (CERT_LEN_PREFIX - 1 - i))) & 0xFF;
- }
-}
-
-static uint32_t ParseCertPrefix(uint8_t *prefix)
+static uint32_t parseCertPrefix(uint8_t *prefix)
{
uint32_t res = 0;
- if(NULL != prefix)
+ if (NULL != prefix)
{
- for(int i=0; i < CERT_LEN_PREFIX; ++i)
+ for (int i = 0; i < CERT_LEN_PREFIX; ++i)
{
res |= (((uint32_t) prefix[i]) << ((CERT_LEN_PREFIX - 1 -i) * BYTE_SIZE));
}
return res;
}
-static uint32_t appendCert2Chain(uint8_t *appendPoint, char *cert, uint32_t max_len)
+static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo)
{
- uint32_t ret = 0;
- VERIFY_NON_NULL(TAG, appendPoint, ERROR);
- VERIFY_NON_NULL(TAG, cert, ERROR);
-
- uint32_t certLen;
- VERIFY_SUCCESS(TAG, B64_OK == b64Decode(cert, strlen(cert), appendPoint + CERT_LEN_PREFIX,
- max_len - CERT_LEN_PREFIX, &certLen), ERROR);
- WriteCertPrefix(appendPoint, certLen);
-
- ret = certLen + CERT_LEN_PREFIX;
-exit:
- return ret;
-}
-
-static OCStackResult GetCAPublicKeyData(CADtlsX509Creds_t *credInfo){
OCStackResult ret = OC_STACK_ERROR;
uint8_t *ccPtr = credInfo->certificateChain;
- for(uint32_t i =0; i < credInfo->chainLen - 1; ++i)
+ for (uint8_t i = 0; i < credInfo->chainLen - 1; ++i)
{
- ccPtr += CERT_LEN_PREFIX + ParseCertPrefix(ccPtr);
+ ccPtr += CERT_LEN_PREFIX + parseCertPrefix(ccPtr);
}
- ByteArray cert = {
- .data = ccPtr + CERT_LEN_PREFIX,
- .len = ParseCertPrefix(ccPtr)
- };
+ ByteArray cert = { .data = ccPtr + CERT_LEN_PREFIX, .len = parseCertPrefix(ccPtr) };
CertificateX509 certStruct;
VERIFY_SUCCESS(TAG, PKI_SUCCESS == DecodeCertificate(cert, &certStruct), ERROR);
return ret;
}
-static OCStackResult GetCertCredPublicData(CADtlsX509Creds_t *credInfo, OicSecCred_t *cred)
+int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
{
- OCStackResult ret = OC_STACK_ERROR;
- cJSON *jsonRoot = NULL;
-
+ int ret = 1;
VERIFY_NON_NULL(TAG, credInfo, ERROR);
- VERIFY_NON_NULL(TAG, cred, ERROR);
- VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
- //VERIFY_SUCCESS(TAG, NULL == credInfo->certificateChain.data, ERROR);
- jsonRoot = cJSON_Parse(cred->publicData.data);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
-
- //Get certificate chain
- cJSON *jsonObj = cJSON_GetObjectItem(jsonRoot, CERTIFICATE);//TODO define field names constants
- VERIFY_SUCCESS(TAG, NULL != jsonObj && cJSON_Array == jsonObj->type, ERROR);
+ if (NULL == gCred)
+ {
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
+ }
- size_t certChainLen = (size_t)cJSON_GetArraySize(jsonObj);
- credInfo->chainLen = certChainLen;
- VERIFY_SUCCESS(TAG, MAX_CHAIN_LEN >= certChainLen, ERROR);
+ OicSecCred_t *cred = NULL;
+ LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
+ VERIFY_NON_NULL(TAG, cred, ERROR);
- uint32_t len = 0;
- for (size_t i = 0; i < certChainLen; ++i)
+ if (cred->publicData.len > MAX_CERT_MESSAGE_LEN || cred->privateData.len > PRIVATE_KEY_SIZE)
{
- cJSON *item = cJSON_GetArrayItem(jsonObj, i);
- VERIFY_NON_NULL(TAG, item, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == item->type, ERROR);
- uint32_t appendedLen = appendCert2Chain(credInfo->certificateChain + len, item->valuestring,
- MAX_CERT_MESSAGE_LEN - len);
- VERIFY_SUCCESS(TAG, 0 != appendedLen, ERROR);
- len += appendedLen;
+ goto exit;
}
- credInfo->certificateChainLen = len;
- VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCAPublicKeyData(credInfo), ERROR);
- ret = OC_STACK_OK;
+ credInfo->chainLen = 2;
+ memcpy(credInfo->certificateChain, cred->publicData.data, cred->publicData.len);
+ memcpy(credInfo->devicePrivateKey, cred->privateData.data, cred->privateData.len);
+ credInfo->certificateChainLen = cred->publicData.len;
+ GetCAPublicKeyData(credInfo);
+ ret = 0;
+
exit:
- cJSON_Delete(jsonRoot);
+
return ret;
}
+#undef CERT_LEN_PREFIX
+#endif /* __WITH_X509__ */
-static OCStackResult GetCertCredPrivateData(CADtlsX509Creds_t *credInfo, OicSecCred_t *cred)
+OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
{
OCStackResult ret = OC_STACK_ERROR;
- cJSON *jsonRoot = NULL;
- VERIFY_NON_NULL(TAG, credInfo, ERROR);
- VERIFY_NON_NULL(TAG, cred, ERROR);
- VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
- jsonRoot = cJSON_Parse(cred->privateData.data);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ uint8_t *cborPayload = NULL;
+ size_t size = 0;
+ OicUuid_t prevId = {.id={0}};
+
+ if(NULL == newROwner)
+ {
+ ret = OC_STACK_INVALID_PARAM;
+ }
+ if(NULL == gCred)
+ {
+ ret = OC_STACK_NO_RESOURCE;
+ }
- cJSON *jsonObj = cJSON_GetObjectItem(jsonRoot, PRIVATE_KEY);//TODO define field names constants
- VERIFY_SUCCESS(TAG, NULL != jsonObj && cJSON_String == jsonObj->type, ERROR);
+ if(newROwner && gCred)
+ {
+ memcpy(prevId.id, gCred->rownerID.id, sizeof(prevId.id));
+ memcpy(gCred->rownerID.id, newROwner->id, sizeof(newROwner->id));
- uint32_t read = 0u;
- VERIFY_SUCCESS(TAG, B64_OK == b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring),
- credInfo->devicePrivateKey, PRIVATE_KEY_SIZE, &read)
- && PRIVATE_KEY_SIZE == read, ERROR);
+ ret = CredToCBORPayload(gCred, &cborPayload, &size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
- ret = OC_STACK_OK;
+ ret = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, cborPayload, size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ OICFree(cborPayload);
+ }
+
+ return ret;
exit:
- cJSON_Delete(jsonRoot);
+ OICFree(cborPayload);
+ memcpy(gCred->rownerID.id, prevId.id, sizeof(prevId.id));
return ret;
}
-int GetDtlsX509Credentials(CADtlsX509Creds_t *credInfo)
+OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
{
- int ret = 1;
- VERIFY_NON_NULL(TAG, credInfo, ERROR);
- if (NULL == gCred)
+ OCStackResult retVal = OC_STACK_ERROR;
+ if (gCred)
{
- VERIFY_SUCCESS(TAG, OC_STACK_OK == InitCredResource(), ERROR);
+ *rowneruuid = gCred->rownerID;
+ retVal = OC_STACK_OK;
}
-
- OicSecCred_t *cred = NULL;
- LL_SEARCH_SCALAR(gCred, cred, credType, SIGNED_ASYMMETRIC_KEY);
- VERIFY_NON_NULL(TAG, cred, ERROR);
-
- VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPrivateData(credInfo, cred), ERROR);
- VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCertCredPublicData(credInfo, cred), ERROR);
-
- ret = 0;
-exit:
-
- return ret;
+ return retVal;
}
-#undef CERT_LEN_PREFIX
-#endif /* __WITH_X509__ */
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <stdlib.h>
-#include <string.h>
-#include "ocstack.h"
-#include "logger.h"
-#include "oic_malloc.h"
-#include "cJSON.h"
-#include "base64.h"
-#include "resourcemanager.h"
-#include "psinterface.h"
#include "utlist.h"
+#include "payload_logging.h"
+#include "psinterface.h"
+#include "resourcemanager.h"
#include "srmresourcestrings.h"
-#include "doxmresource.h"
#include "srmutility.h"
+#include "doxmresource.h"
+#include "ocpayload.h"
+#include "oic_malloc.h"
#ifdef __WITH_X509__
#include "crlresource.h"
#include "crl.h"
#define SEPARATOR ":"
#define SEPARATOR_LEN (1)
-#define JSON_CRL_NAME "\"CRL\""
-#define JSON_CRL_NAME_LEN (5)
-#define OIC_JSON_CRL_NAME "crl"
-#define OIC_JSON_CRL_ID "CRLId"
-#define OIC_JSON_CRL_THIS_UPDATE "ThisUpdate"
-#define OIC_JSON_CRL_DATA "CRLData"
-#define CRL_DEFAULT_CRL_ID 1
+#define CBOR_CRL_NAME "\"CRL\""
+#define CBOR_CRL_NAME_LEN (5)
+#define OIC_CBOR_CRL_NAME "crl"
+#define OIC_CBOR_CRL_ID "CRLId"
+#define OIC_CBOR_CRL_THIS_UPDATE "ThisUpdate"
+#define OIC_CBOR_CRL_DATA "CRLData"
+#define CRL_DEFAULT_CRL_ID (1)
#define CRL_DEFAULT_THIS_UPDATE "150101000000Z"
#define CRL_DEFAULT_CRL_DATA "-"
static OCResourceHandle gCrlHandle = NULL;
static OicSecCrl_t *gCrl = NULL;
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching below max cbor size. */
+static const uint16_t CBOR_SIZE = 1024;
+
+// Max cbor size payload.
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+// PSTAT Map size - Number of mandatory items
+static const uint8_t CRL_MAP_SIZE = 3;
void DeleteCrlBinData(OicSecCrl_t *crl)
{
}
}
-char *BinToCrlJSON(const OicSecCrl_t *crl)
+OCStackResult CrlToCBORPayload(const OicSecCrl_t *crl, uint8_t **payload, size_t *size)
{
- if (NULL == crl)
+ if (NULL == crl || NULL == payload || NULL != *payload || NULL == size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ size_t cborLen = *size;
+ if (0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
}
- char *base64Buff = NULL;
- uint32_t outLen = 0;
- uint32_t base64CRLLen = 0;
- B64Result b64Ret = B64_OK;
- char *jsonStr = NULL;
- cJSON *jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
- cJSON *jsonCrl = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
+ *payload = NULL;
+ *size = 0;
- cJSON_AddItemToObject(jsonRoot, OIC_JSON_CRL_NAME, jsonCrl);
+ OCStackResult ret = OC_STACK_ERROR;
+
+ CborEncoder encoder;
+ CborEncoder crlMap;
+
+ CborError cborEncoderResult = CborNoError;
+
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &crlMap, CRL_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create CRL Map");
//CRLId -- Mandatory
- cJSON_AddNumberToObject(jsonCrl, OIC_JSON_CRL_ID, (int)crl->CrlId);
+ cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_ID,
+ strlen(OIC_CBOR_CRL_ID));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add CRL ID");
+ cborEncoderResult = cbor_encode_int(&crlMap, crl->CrlId);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add CRL Id value");
//ThisUpdate -- Mandatory
- outLen = 0;
- base64CRLLen = (uint32_t)B64ENCODE_OUT_SAFESIZE(crl->ThisUpdate.len);
- base64Buff = OICMalloc(base64CRLLen);
- b64Ret = b64Encode(crl->ThisUpdate.data, crl->ThisUpdate.len, base64Buff,
- base64CRLLen, &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_THIS_UPDATE, base64Buff);
- OICFree(base64Buff);
+ cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_THIS_UPDATE,
+ strlen(OIC_CBOR_CRL_THIS_UPDATE));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl update");
+ cborEncoderResult = cbor_encode_byte_string(&crlMap, crl->ThisUpdate.data,
+ crl->ThisUpdate.len);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl Update value");
//CRLData -- Mandatory
- outLen = 0;
- base64CRLLen = (uint32_t)B64ENCODE_OUT_SAFESIZE(crl->CrlData.len);
- base64Buff = OICMalloc(base64CRLLen);
- b64Ret = b64Encode(crl->CrlData.data, crl->CrlData.len, base64Buff,
- base64CRLLen, &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonCrl, OIC_JSON_CRL_DATA, base64Buff);
-
- jsonStr = cJSON_PrintUnformatted(jsonRoot);
+ cborEncoderResult = cbor_encode_text_string(&crlMap, OIC_CBOR_CRL_DATA,
+ strlen(OIC_CBOR_CRL_DATA));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl data name");
+ cborEncoderResult = cbor_encode_byte_string(&crlMap, crl->CrlData.data,
+ crl->CrlData.len);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add Crl data value");
+
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &crlMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to add close Crl map");
+
+ *size = encoder.ptr - outPayload;
+ *payload = outPayload;
+ ret = OC_STACK_OK;
exit:
- OICFree(base64Buff);
- if (jsonRoot)
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
{
- cJSON_Delete(jsonRoot);
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = CrlToCBORPayload(crl, payload, &cborLen);
}
- return jsonStr;
+
+ if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *payload = NULL;
+ *size = 0;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
}
-OicSecCrl_t *JSONToCrlBin(const char * jsonStr)
+OCStackResult CBORPayloadToCrl(const uint8_t *cborPayload, const size_t size,
+ OicSecCrl_t **secCrl)
{
- if (NULL == jsonStr)
+ if (NULL == cborPayload || NULL == secCrl || NULL != *secCrl || 0 == size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
OCStackResult ret = OC_STACK_ERROR;
- OicSecCrl_t *crl = NULL;
- cJSON *jsonCrl = NULL;
- cJSON *jsonObj = NULL;
+ *secCrl = NULL;
- unsigned char *base64Buff = NULL;
- uint32_t base64CRLLen = 0;
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
+ CborValue crlCbor = {.parser = NULL};
+ CborParser parser = {.end = NULL};
+ CborError cborFindResult = CborNoError;
- cJSON *jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ cbor_parser_init(cborPayload, size, 0, &parser, &crlCbor);
+ CborValue crlMap = { .parser = NULL};
+ OicSecCrl_t *crl = NULL;
+ size_t outLen = 0;
+ cborFindResult = cbor_value_enter_container(&crlCbor, &crlMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter Crl map");
- jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
- VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
crl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
VERIFY_NON_NULL(TAG, crl, ERROR);
- //CRLId -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_ID);
- if(jsonObj)
- {
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- crl->CrlId = (uint16_t)jsonObj->valueint;
- }
- else // PUT/POST JSON may not have CRLId so set it to the gCRList->CRLId
+ cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_ID, &crlMap);
+ if (CborNoError == cborFindResult && cbor_value_is_integer(&crlMap))
{
- VERIFY_NON_NULL(TAG, gCrl, ERROR);
- crl->CrlId = gCrl->CrlId;
+ cborFindResult = cbor_value_get_int(&crlMap, (int *) &crl->CrlId);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CrlId.");
}
- //ThisUpdate -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_THIS_UPDATE);
- if(jsonObj)
+ cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_THIS_UPDATE, &crlMap);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&crlMap))
{
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- if(cJSON_String == jsonObj->type)
- {
- //Check for empty string, in case ThisUpdate field has not been set yet
- if (jsonObj->valuestring[0])
- {
- base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
- base64Buff = OICMalloc(base64CRLLen);
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- base64CRLLen, &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
- ERROR);
- crl->ThisUpdate.data = OICMalloc(outLen + 1);
- memcpy(crl->ThisUpdate.data, base64Buff, outLen);
- crl->ThisUpdate.len = outLen;
- OICFree(base64Buff);
- base64Buff = NULL;
- }
- }
+ cborFindResult = cbor_value_dup_byte_string(&crlMap,
+ &crl->ThisUpdate.data, &crl->ThisUpdate.len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Byte Array.");
}
- else // PUT/POST JSON will not have ThisUpdate so set it to the gCRList->ThisUpdate
+ cborFindResult = cbor_value_map_find_value(&crlCbor, OIC_CBOR_CRL_DATA, &crlMap);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&crlMap))
{
- VERIFY_NON_NULL(TAG, gCrl, ERROR);
- outLen = (uint32_t)gCrl->ThisUpdate.len;
- crl->ThisUpdate.data = OICMalloc(outLen + 1);
- memcpy(crl->ThisUpdate.data, gCrl->ThisUpdate.data, outLen);
- crl->ThisUpdate.len = outLen;
+ cborFindResult = cbor_value_dup_byte_string(&crlMap,
+ &crl->CrlData.data, &crl->CrlData.len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Byte Array.");
}
- //CRLData -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
- if(jsonObj)
+ *secCrl = crl;
+ ret = OC_STACK_OK;
+exit:
+ if (CborNoError != cborFindResult)
{
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- if(cJSON_String == jsonObj->type)
+ // PUT/POST CBOR may not have mandatory values set default values.
+ if (gCrl)
{
- //Check for empty string, in case CRLData field has not been set yet
- if (jsonObj->valuestring[0])
+ OIC_LOG (DEBUG, TAG, "Set default values");
+ crl->CrlId = gCrl->CrlId;
+ if (crl->ThisUpdate.data)
+ {
+ OICFree(crl->ThisUpdate.data);
+ }
+ outLen = gCrl->ThisUpdate.len;
+ crl->ThisUpdate.data = (uint8_t*) OICMalloc(outLen);
+ if (crl->ThisUpdate.data)
{
- outLen = 0;
- base64CRLLen = B64ENCODE_OUT_SAFESIZE(strlen(jsonObj->valuestring));
- base64Buff = OICMalloc(base64CRLLen);
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- base64CRLLen, &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= base64CRLLen),
- ERROR);
- crl->CrlData.data = OICMalloc(outLen + 1);
- memcpy(crl->CrlData.data, base64Buff, outLen);
+ memcpy(crl->ThisUpdate.data, gCrl->ThisUpdate.data, outLen);
+ crl->ThisUpdate.len = outLen;
+ }
+ else
+ {
+ crl->ThisUpdate.len = 0;
+ OIC_LOG(ERROR, TAG, "Set default failed");
+ }
+ if (crl->CrlData.data)
+ {
+ OICFree(crl->CrlData.data);
+ }
+ outLen = gCrl->CrlData.len;
+ crl->CrlData.data = (uint8_t*) OICMalloc(outLen);
+ if (crl->CrlData.data && gCrl->CrlData.data)
+ {
+ memcpy(crl->CrlData.data, gCrl->CrlData.data, outLen);
crl->CrlData.len = outLen;
- OICFree(base64Buff);
- base64Buff = NULL;
}
- }
- }
- else // PUT/POST JSON will not have CRLData so set it to the gCRList->CRLData
- {
- VERIFY_NON_NULL(TAG, gCrl, ERROR);
- outLen = (uint32_t)gCrl->CrlData.len;
- crl->CrlData.data = OICMalloc(outLen + 1);
- memcpy(crl->CrlData.data, gCrl->CrlData.data, outLen);
- crl->CrlData.len = outLen;
- }
+ else
+ {
+ crl->CrlData.len = 0;
+ OIC_LOG (ERROR, TAG, "Set default failed");
+ }
- ret = OC_STACK_OK;
-exit:
- cJSON_Delete(jsonRoot);
- OICFree(base64Buff);
- base64Buff = NULL;
- if (OC_STACK_OK != ret)
- {
- DeleteCrlBinData(crl);
- crl = NULL;
+ *secCrl = crl;
+ ret = OC_STACK_OK;
+ }
+ else
+ {
+ OIC_LOG (ERROR, TAG, "CBORPayloadToCrl failed");
+ DeleteCrlBinData(crl);
+ crl = NULL;
+ ret = OC_STACK_ERROR;
+ }
}
- return crl;
+ return ret;
}
OCStackResult UpdateCRLResource(const OicSecCrl_t *crl)
{
- char *jsonStr = NULL;
- OCStackResult res = OC_STACK_ERROR;
-
- jsonStr = BinToCrlJSON((OicSecCrl_t *) crl);
- if (!jsonStr)
- {
- return OC_STACK_ERROR;
- }
-
- cJSON *jsonObj = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
+ uint8_t *payload = NULL;
+ size_t size = 0;
- if (jsonObj == NULL)
+ OCStackResult res = CrlToCBORPayload((OicSecCrl_t *) crl, &payload, &size);
+ if (OC_STACK_OK != res)
{
- return OC_STACK_ERROR;
+ return res;
}
- res = UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj);
- cJSON_Delete(jsonObj);
-
- return res;
+ return UpdateSecureResourceInPS(OIC_CBOR_CRL_NAME, payload, size);
}
static OCEntityHandlerResult HandleCRLPostRequest(const OCEntityHandlerRequest *ehRequest)
{
OCEntityHandlerResult ehRet = OC_EH_ERROR;
+ OicSecCrl_t *crl = NULL;
+ uint8_t *payload = ((OCSecurityPayload *)ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
- char *jsonCRL = (char *)(((OCSecurityPayload *)ehRequest->payload)->securityData);
-
- if (jsonCRL)
+ if (payload)
{
OIC_LOG(INFO, TAG, "UpdateSVRDB...");
- OIC_LOG_V(INFO, TAG, "crl: \"%s\"", jsonCRL);
-
- cJSON *jsonObj = cJSON_Parse(jsonCRL);
- OicSecCrl_t *crl = NULL;
- crl = JSONToCrlBin(jsonCRL);
+ CBORPayloadToCrl(payload, size, &crl);
VERIFY_NON_NULL(TAG, crl, ERROR);
gCrl->CrlId = crl->CrlId;
OICFree(gCrl->ThisUpdate.data);
gCrl->ThisUpdate.data = NULL;
gCrl->ThisUpdate.data = OICMalloc(crl->ThisUpdate.len);
+ VERIFY_NON_NULL(TAG, gCrl->ThisUpdate.data, ERROR);
memcpy(gCrl->ThisUpdate.data, crl->ThisUpdate.data, crl->ThisUpdate.len);
gCrl->ThisUpdate.len = crl->ThisUpdate.len;
OICFree(gCrl->CrlData.data);
- gCrl->CrlData.data = NULL;
gCrl->CrlData.data = OICMalloc(crl->CrlData.len);
+ VERIFY_NON_NULL(TAG, gCrl->CrlData.data, ERROR);
memcpy(gCrl->CrlData.data, crl->CrlData.data, crl->CrlData.len);
gCrl->CrlData.len = crl->CrlData.len;
- if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_CRL_NAME, jsonObj))
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_CBOR_CRL_NAME, payload, size))
{
- OIC_LOG(INFO, TAG, "UpdateSVRDB == OK");
ehRet = OC_EH_RESOURCE_CREATED;
}
DeleteCrlBinData(crl);
-
- exit:
- cJSON_Delete(jsonObj);
}
+exit:
// Send payload to request originator
- SendSRMResponse(ehRequest, ehRet, NULL);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleCRLPostRequest");
+ }
OIC_LOG_V(INFO, TAG, "%s RetVal %d", __func__, ehRet);
return ehRet;
}
-/*
+/**
* This internal method is the entity handler for CRL resource and
* will handle REST request (GET/PUT/POST/DEL) for them.
*/
-OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
- OCEntityHandlerRequest *ehRequest,
- void *callbackParameter)
+static OCEntityHandlerResult CRLEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest *ehRequest,
+ void *callbackParameter)
{
OCEntityHandlerResult ehRet = OC_EH_ERROR;
(void)callbackParameter;
default:
ehRet = OC_EH_ERROR;
- SendSRMResponse(ehRequest, ehRet, NULL);
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
}
}
return ehRet;
}
-/*
+/**
* This internal method is used to create '/oic/sec/crl' resource.
*/
-OCStackResult CreateCRLResource()
+static OCStackResult CreateCRLResource()
{
- OCStackResult ret;
- ret = OCCreateResource(&gCrlHandle,
- OIC_RSRC_TYPE_SEC_CRL,
- OIC_MI_DEF,
- OIC_RSRC_CRL_URI,
- CRLEntityHandler,
- NULL,
- OC_OBSERVABLE);
+ OCStackResult ret = OCCreateResource(&gCrlHandle,
+ OIC_RSRC_TYPE_SEC_CRL,
+ OIC_MI_DEF,
+ OIC_RSRC_CRL_URI,
+ CRLEntityHandler,
+ NULL,
+ OC_OBSERVABLE);
if (OC_STACK_OK != ret)
{
}
/**
- * Get the default value
- * @retval NULL for now. Update it when we finalize the default info.
+ * Get the default value.
+ * @return defaultCrl for now.
*/
static OicSecCrl_t *GetCrlDefault()
{
- OicSecCrl_t *defaultCrl = NULL;
- defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
-
+ OicSecCrl_t *defaultCrl = (OicSecCrl_t *)OICCalloc(1, sizeof(OicSecCrl_t));
+ if (NULL == defaultCrl)
+ {
+ return NULL;
+ }
defaultCrl->CrlId = CRL_DEFAULT_CRL_ID;
defaultCrl->CrlData.len = strlen(CRL_DEFAULT_CRL_DATA);
- defaultCrl->CrlData.data = OICMalloc(defaultCrl->CrlData.len);
- memcpy(defaultCrl->CrlData.data, CRL_DEFAULT_CRL_DATA, defaultCrl->CrlData.len);
+ defaultCrl->CrlData.data = (uint8_t*) OICMalloc(defaultCrl->CrlData.len);
+ if (defaultCrl->CrlData.data)
+ {
+ memcpy(defaultCrl->CrlData.data, CRL_DEFAULT_CRL_DATA, defaultCrl->CrlData.len);
+ }
+ else
+ {
+ defaultCrl->CrlData.len = 0;
+ }
defaultCrl->ThisUpdate.len = strlen(CRL_DEFAULT_THIS_UPDATE);
- defaultCrl->ThisUpdate.data = OICMalloc(defaultCrl->ThisUpdate.len);
- memcpy(defaultCrl->ThisUpdate.data, CRL_DEFAULT_THIS_UPDATE, defaultCrl->ThisUpdate.len);
+ defaultCrl->ThisUpdate.data = (uint8_t*) OICMalloc(defaultCrl->ThisUpdate.len);
+ if (defaultCrl->ThisUpdate.data)
+ {
+ memcpy(defaultCrl->ThisUpdate.data, CRL_DEFAULT_THIS_UPDATE, defaultCrl->ThisUpdate.len);
+ }
+ else
+ {
+ defaultCrl->ThisUpdate.len = 0;
+ }
return defaultCrl;
}
OCStackResult InitCRLResource()
{
OCStackResult ret = OC_STACK_ERROR;
- char* jsonSVRDatabase;
-
- //Read CRL resource from PS
- jsonSVRDatabase = GetSVRDatabase();
-
- if (jsonSVRDatabase)
+ // Read Crl resource from PS
+ uint8_t *data = NULL;
+ size_t size = 0;
+ ret = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
+ // If database read failed
+ if (OC_STACK_OK != ret)
{
- //Convert JSON CRL into binary format
- gCrl = JSONToCrlBin(jsonSVRDatabase);
+ OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
}
+ if (data)
+ {
+ // Read ACL resource from PS
+ ret = CBORPayloadToCrl(data, size, &gCrl);
+ }
+
/*
* If SVR database in persistent storage got corrupted or
* is not available for some reason, a default CrlResource is created
* which allows user to initiate CrlResource provisioning again.
*/
- if (!jsonSVRDatabase || !gCrl)
+ if ((OC_STACK_OK != ret) || !data || !gCrl)
{
gCrl = GetCrlDefault();
}
ret = CreateCRLResource();
- OICFree(jsonSVRDatabase);
+ OICFree(data);
return ret;
}
OicSecCrl_t *crl = NULL;
//Read CRL resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
-
- if (jsonSVRDatabase)
+ uint8_t *data = NULL;
+ size_t size = 0;
+ OCStackResult ret = GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size);
+ if (data)
{
- //Convert JSON CRL into binary format
- crl = JSONToCrlBin(jsonSVRDatabase);
+ //Convert CBOR CRL into binary format
+ ret = CBORPayloadToCrl(data, size, &crl);
}
/*
* If SVR database in persistent storage got corrupted or
* is not available for some reason, a default CrlResource is created
* which allows user to initiate CrlResource provisioning again.
*/
- if (!jsonSVRDatabase || !crl)
+ if ((OC_STACK_OK != ret) || !data || !crl)
{
crl = GetCrlDefault();
}
- OICFree(jsonSVRDatabase);
+ OICFree(data);
return crl;
}
-char *GetBase64CRL()
+uint8_t *GetCrl()
{
- cJSON *jsonCrl = NULL;
- cJSON *jsonObj = NULL;
- char *jsonSVRDatabase = GetSVRDatabase();
- char* ret = NULL;
-
- cJSON *jsonRoot = cJSON_Parse(jsonSVRDatabase);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
-
- jsonCrl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRL_NAME);
- VERIFY_NON_NULL(TAG, jsonCrl, ERROR);
-
- //CRLData -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonCrl, OIC_JSON_CRL_DATA);
- if(jsonObj)
+ uint8_t *data = NULL;
+ size_t size = 0;
+ OicSecCrl_t *crl = NULL;
+ if (OC_STACK_OK == GetSecureVirtualDatabaseFromPS(OIC_CBOR_CRL_NAME, &data, &size) && data &&
+ OC_STACK_OK == CBORPayloadToCrl(data, size, &crl))
{
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- if(cJSON_String == jsonObj->type)
- {
- //Check for empty string, in case CRLData field has not been set yet
- if (jsonObj->valuestring[0])
- {
- ret = jsonObj->valuestring;
- }
- }
+ return crl->CrlData.data;
}
-exit:
- OICFree(jsonSVRDatabase);
- cJSON_Delete(jsonRoot);
- return ret;
+ return NULL;
}
void GetDerCrl(ByteArray crlArray)
#ifndef _POSIX_C_SOURCE\r
#define _POSIX_C_SOURCE 200112L\r
#endif\r
-\r
#ifndef WITH_ARDUINO\r
#include <unistd.h>\r
-#include <string.h>\r
#include <time.h>\r
#include <sys/time.h>\r
#endif\r
\r
\r
#define TAG ("DP")\r
+static const uint16_t CBOR_SIZE = 1024;\r
\r
/**\r
* Structure to carry direct-pairing API data to callback.\r
static OCDirectPairingDev_t *g_dp_discover = NULL;\r
static DPairData_t *g_dp_proceed_ctx = NULL;\r
\r
+\r
/**\r
* Function to search node in linked list that matches given IP and port.\r
*\r
pconf->prm = NULL; // to prevent free\r
ptr->prmLen = pconf->prmLen;\r
memcpy(&ptr->deviceID, &pconf->deviceID, sizeof(OicUuid_t));\r
- memcpy(&ptr->rowner, &pconf->rowner, sizeof(OicUuid_t));\r
+ memcpy(&ptr->rowner, &pconf->rownerID, sizeof(OicUuid_t));\r
ptr->next = NULL;\r
\r
LL_PREPEND(*ppList, ptr);\r
if(OC_STACK_OK == clientResponse->result)\r
{\r
// result\r
- OIC_LOG(INFO, TAG, "DirectPairingFinalizeHandler : success PUT request to /oic/sec/dpairing");\r
+ OIC_LOG(INFO, TAG, "DirectPairingFinalizeHandler : success PUT"\r
+ " request to /oic/sec/dpairing");\r
\r
CAEndpoint_t endpoint;\r
memset(&endpoint, 0x00, sizeof(CAEndpoint_t));\r
OIC_LOG(INFO, TAG, "Direct-Papring was successfully completed.");\r
\r
// update paired list\r
- OCDirectPairingDev_t *dev = getDev(&g_dp_discover, peer->endpoint.addr, peer->endpoint.port);\r
+ OCDirectPairingDev_t *dev = getDev(&g_dp_discover, peer->endpoint.addr,\r
+ peer->endpoint.port);\r
res = addDev2(&g_dp_paired, dev);\r
if (OC_STACK_OK != res)\r
{\r
return OC_STACK_NO_MEMORY;\r
}\r
secPayload->base.type = PAYLOAD_TYPE_SECURITY;\r
- secPayload->securityData = BinToDpairingJSON(&dpair);\r
- if(NULL == secPayload->securityData)\r
+\r
+ OCStackResult ret = DpairingToCBORPayload(&dpair, &(secPayload->securityData),\r
+ &(secPayload->payloadSize));\r
+\r
+ if(OC_STACK_OK != ret)\r
{\r
OICFree(secPayload);\r
- OIC_LOG(ERROR, TAG, "Failed to BinToDpairingJSON");\r
+ OIC_LOG(ERROR, TAG, "Failed to DpairingToCBORPayload");\r
return OC_STACK_NO_MEMORY;\r
}\r
- OIC_LOG_V(INFO, TAG, "DPARING : %s", secPayload->securityData);\r
+ OIC_LOG(INFO, TAG, "DPARING CBOR data:");\r
+ OIC_LOG_BUFFER(INFO, TAG, secPayload->securityData, secPayload->payloadSize);\r
\r
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};\r
if(!DPGenerateQuery(true,\r
OCMethod method = OC_REST_PUT;\r
OCDoHandle handle = NULL;\r
OIC_LOG(DEBUG, TAG, "Sending DPAIRNG setting to resource server");\r
- OCStackResult ret = OCDoResource(&handle, method, query,\r
+ ret = OCDoResource(&handle, method, query,\r
&peer->endpoint, (OCPayload*)secPayload,\r
peer->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
if(OC_STACK_OK != ret)\r
res = AddTmpPskWithPIN(&dpairData->peer->deviceID,\r
SYMMETRIC_PAIR_WISE_KEY,\r
(char*)dpairData->pin, DP_PIN_LENGTH,\r
- 1, &dpairData->peer->rowner, &subjectId);\r
+ &dpairData->peer->rowner, &subjectId);\r
VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);\r
\r
\r
VERIFY_NON_NULL(TAG, endpoint, FATAL);\r
memcpy(endpoint,&dpairData->peer->endpoint,sizeof(CAEndpoint_t));\r
endpoint->port = dpairData->peer->securePort;\r
- OIC_LOG_V(INFO, TAG, "Initiate DTLS handshake to %s(%d)", endpoint->addr, endpoint->port);\r
+ OIC_LOG_V(INFO, TAG, "Initiate DTLS handshake to %s(%d)", endpoint->addr,\r
+ endpoint->port);\r
\r
caresult = CAInitiateHandshake(endpoint);\r
OICFree(endpoint);\r
return OC_STACK_NO_MEMORY;\r
}\r
secPayload->base.type = PAYLOAD_TYPE_SECURITY;\r
- secPayload->securityData = BinToDpairingJSON(&dpair);\r
- if(NULL == secPayload->securityData)\r
+\r
+ OCStackResult ret = DpairingToCBORPayload(&dpair, &(secPayload->securityData),\r
+ &(secPayload->payloadSize));\r
+\r
+ if(OC_STACK_OK != ret)\r
{\r
OICFree(secPayload);\r
- OIC_LOG(ERROR, TAG, "Failed to BinToDpairingJSON");\r
+ OIC_LOG(ERROR, TAG, "Failed to DpairingToCBORPayload");\r
return OC_STACK_NO_MEMORY;\r
}\r
- OIC_LOG_V(INFO, TAG, "DPAIRING : %s", secPayload->securityData);\r
+ OIC_LOG(INFO, TAG, "DPARING CBOR data:");\r
+ OIC_LOG_BUFFER(INFO, TAG, secPayload->securityData, secPayload->payloadSize);\r
\r
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};\r
if(!DPGenerateQuery(false,\r
OCMethod method = OC_REST_POST;\r
OCDoHandle handle = NULL;\r
OIC_LOG(DEBUG, TAG, "Sending DPAIRNG setting to resource server");\r
- OCStackResult ret = OCDoResource(&handle, method, query,\r
+ ret = OCDoResource(&handle, method, query,\r
&peer->endpoint, (OCPayload*)secPayload,\r
peer->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
if(OC_STACK_OK != ret)\r
static OCStackApplicationResult DirectPairingPortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,\r
OCClientResponse *clientResponse)\r
{\r
- OIC_LOG(INFO, TAG, "Callback Context for Direct-Pairing Secure Port DISCOVER query recvd successfully");\r
+ OIC_LOG(INFO, TAG, "Callback Context for Direct-Pairing Secure Port DISCOVER "\r
+ "query recvd successfully");\r
\r
(void)ctx;\r
(void)UNUSED;\r
}\r
\r
OIC_LOG_PAYLOAD(INFO, clientResponse->payload);\r
- OicSecPconf_t *pconf = JSONToPconfBin(\r
- ((OCSecurityPayload*)clientResponse->payload)->securityData);\r
- if (NULL == pconf)\r
+ OicSecPconf_t *pconf = NULL;\r
+\r
+ OCStackResult res = CBORPayloadToPconf(\r
+ ((OCSecurityPayload*)clientResponse->payload)->securityData,\r
+ CBOR_SIZE,&pconf);\r
+ if (OC_STACK_OK != res )\r
{\r
- OIC_LOG(INFO, TAG, "Ignoring malformed JSON");\r
+ OIC_LOG(INFO, TAG, "Ignoring malformed CBOR");\r
return OC_STACK_KEEP_TRANSACTION;\r
}\r
else\r
{\r
- OCDevAddr endpoint;\r
- memcpy(&endpoint, &clientResponse->devAddr, sizeof(OCDevAddr));\r
-\r
- OCStackResult res = addDev(&g_dp_discover, &endpoint,\r
- clientResponse->connType, pconf);\r
- DeletePconfBinData(pconf);\r
- if (OC_STACK_OK != res)\r
+ if(pconf->edp)\r
{\r
- OIC_LOG(ERROR, TAG, "Error while adding data to linkedlist.");\r
- return OC_STACK_KEEP_TRANSACTION;\r
- }\r
+ OCDevAddr endpoint;\r
+ memcpy(&endpoint, &clientResponse->devAddr, sizeof(OCDevAddr));\r
\r
+ OCStackResult res = addDev(&g_dp_discover, &endpoint,\r
+ clientResponse->connType, pconf);\r
+ DeletePconfBinData(pconf);\r
+ if (OC_STACK_OK != res)\r
+ {\r
+ OIC_LOG(ERROR, TAG, "Error while adding data to linkedlist.");\r
+ return OC_STACK_KEEP_TRANSACTION;\r
+ }\r
\r
- char rsrc_uri[MAX_URI_LENGTH+1] = {0};\r
- int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",\r
- OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DPAIRING);\r
- if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))\r
- {\r
- OIC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");\r
- return OC_STACK_KEEP_TRANSACTION;\r
- }\r
\r
- //Try to the unicast discovery to getting secure port\r
- char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};\r
- if(!DPGenerateQuery(false,\r
- clientResponse->devAddr.addr, clientResponse->devAddr.port,\r
- clientResponse->connType,\r
- query, sizeof(query), rsrc_uri))\r
- {\r
- OIC_LOG(ERROR, TAG, "DirectPairingDiscoveryHandler : Failed to generate query");\r
- return OC_STACK_KEEP_TRANSACTION;\r
- }\r
- OIC_LOG_V(DEBUG, TAG, "Query=%s", query);\r
-\r
- OCCallbackData cbData;\r
- cbData.cb = &DirectPairingPortDiscoveryHandler;\r
- cbData.context = NULL;\r
- cbData.cd = NULL;\r
- OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,\r
- clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
- if(OC_STACK_OK != ret)\r
- {\r
- OIC_LOG(ERROR, TAG, "Failed to Secure Port Discovery");\r
- return OC_STACK_KEEP_TRANSACTION;\r
- }\r
- else\r
- {\r
- OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);\r
- }\r
+ char rsrc_uri[MAX_URI_LENGTH+1] = {0};\r
+ int wr_len = snprintf(rsrc_uri, sizeof(rsrc_uri), "%s?%s=%s",\r
+ OC_RSRVD_WELL_KNOWN_URI, OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DPAIRING);\r
+ if(wr_len <= 0 || (size_t)wr_len >= sizeof(rsrc_uri))\r
+ {\r
+ OIC_LOG(ERROR, TAG, "rsrc_uri_string_print failed");\r
+ return OC_STACK_KEEP_TRANSACTION;\r
+ }\r
\r
+ //Try to the unicast discovery to getting secure port\r
+ char query[MAX_URI_LENGTH+MAX_QUERY_LENGTH+1] = {0};\r
+ if(!DPGenerateQuery(false,\r
+ clientResponse->devAddr.addr, clientResponse->devAddr.port,\r
+ clientResponse->connType,\r
+ query, sizeof(query), rsrc_uri))\r
+ {\r
+ OIC_LOG(ERROR, TAG, "DirectPairingDiscoveryHandler : Failed to generate query");\r
+ return OC_STACK_KEEP_TRANSACTION;\r
+ }\r
+ OIC_LOG_V(DEBUG, TAG, "Query=%s", query);\r
+\r
+ OCCallbackData cbData;\r
+ cbData.cb = &DirectPairingPortDiscoveryHandler;\r
+ cbData.context = NULL;\r
+ cbData.cd = NULL;\r
+ OCStackResult ret = OCDoResource(NULL, OC_REST_DISCOVER, query, 0, 0,\r
+ clientResponse->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
+ if(OC_STACK_OK != ret)\r
+ {\r
+ OIC_LOG(ERROR, TAG, "Failed to Secure Port Discovery");\r
+ return OC_STACK_KEEP_TRANSACTION;\r
+ }\r
+ else\r
+ {\r
+ OIC_LOG_V(INFO, TAG, "OCDoResource with [%s] Success", query);\r
+ }\r
+ }\r
return OC_STACK_KEEP_TRANSACTION;\r
}\r
}\r
\r
return OC_STACK_DELETE_TRANSACTION;\r
}\r
-\r
#ifndef WITH_ARDUINO\r
/**\r
* Discover direct-pairing devices in the same IP subnet. .\r
// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#ifdef __WITH_DTLS__
+#include "global.h"
+#endif
#include "ocstack.h"
-#include "logger.h"
#include "oic_malloc.h"
-#include "cJSON.h"
+#include "payload_logging.h"
+#include "utlist.h"
+#include "ocrandom.h"
+#include "ocpayload.h"
+#include "cainterface.h"
+#include "ocserverrequest.h"
#include "resourcemanager.h"
#include "doxmresource.h"
#include "pstatresource.h"
#include "aclresource.h"
+#include "amaclresource.h"
+#include "pconfresource.h"
+#include "dpairingresource.h"
#include "psinterface.h"
-#include "utlist.h"
#include "srmresourcestrings.h"
#include "securevirtualresourcetypes.h"
-#include "base64.h"
-#include "ocrandom.h"
-#include "cainterface.h"
#include "credresource.h"
-#include "ocserverrequest.h"
#include "srmutility.h"
#include "pinoxmcommon.h"
-#ifdef __WITH_DTLS__
-#include "global.h"
-#endif
+#define TAG "SRM-DOXM"
-#include <stdlib.h>
-#include <string.h>
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching belox max cbor size. */
+static const uint16_t CBOR_SIZE = 512;
-#if HAVE_STRINGS_H
-#include <strings.h>
-#endif
+/** Max cbor size payload. */
+static const uint16_t CBOR_MAX_SIZE = 4400;
-#define TAG "SRM-DOXM"
+/** DOXM Map size - Number of mandatory items. */
+static const uint8_t DOXM_MAP_SIZE = 7;
static OicSecDoxm_t *gDoxm = NULL;
static OCResourceHandle gDoxmHandle = NULL;
{.id = {0}}, /* OicUuid_t deviceID */
false, /* bool dpc */
{.id = {0}}, /* OicUuid_t owner */
+ {.id = {0}}, /* OicUuid_t rownerID */
};
void DeleteDoxmBinData(OicSecDoxm_t* doxm)
}
}
-char * BinToDoxmJSON(const OicSecDoxm_t * doxm)
+OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, size_t *size)
{
- if (NULL == doxm)
+ if (NULL == doxm || NULL == payload || NULL != *payload || NULL == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ size_t cborLen = *size;
+ if (0 == cborLen)
{
- return NULL;
+ cborLen = CBOR_SIZE;
}
+ *payload = NULL;
+ *size = 0;
- char *jsonStr = NULL;
- cJSON *jsonDoxm = NULL;
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
+ OCStackResult ret = OC_STACK_ERROR;
+
+ CborEncoder encoder;
+ CborEncoder doxmMap;
+ char* strUuid = NULL;
+
+ int64_t cborEncoderResult = CborNoError;
+ uint8_t mapSize = DOXM_MAP_SIZE;
+ if (doxm->oxmTypeLen > 0)
+ {
+ mapSize++;
+ }
+ if (doxm->oxmLen > 0)
+ {
+ mapSize++;
+ }
- cJSON *jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
- jsonDoxm = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonDoxm, ERROR);
- cJSON_AddItemToObject(jsonRoot, OIC_JSON_DOXM_NAME, jsonDoxm );
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &doxmMap, mapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Map.");
//OxmType -- Not Mandatory
- if(doxm->oxmTypeLen > 0)
+ if (doxm->oxmTypeLen > 0)
{
- cJSON *jsonOxmTyArray = cJSON_CreateArray();
- VERIFY_NON_NULL(TAG, jsonOxmTyArray, ERROR);
- cJSON_AddItemToObject (jsonDoxm, OIC_JSON_OXM_TYPE_NAME, jsonOxmTyArray );
+ CborEncoder oxmType;
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXM_TYPE_NAME,
+ strlen(OIC_JSON_OXM_TYPE_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&doxmMap, &oxmType, doxm->oxmTypeLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Array.");
+
for (size_t i = 0; i < doxm->oxmTypeLen; i++)
{
- cJSON_AddItemToArray (jsonOxmTyArray, cJSON_CreateString(doxm->oxmType[i]));
+ cborEncoderResult = cbor_encode_text_string(&oxmType, doxm->oxmType[i],
+ strlen(doxm->oxmType[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmType Value.");
}
+ cborEncoderResult = cbor_encoder_close_container(&doxmMap, &oxmType);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxmType.");
}
//Oxm -- Not Mandatory
- if(doxm->oxmLen > 0)
+ if (doxm->oxmLen > 0)
{
- cJSON *jsonOxmArray = cJSON_CreateArray();
- VERIFY_NON_NULL(TAG, jsonOxmArray, ERROR);
- cJSON_AddItemToObject (jsonDoxm, OIC_JSON_OXM_NAME,jsonOxmArray );
+ CborEncoder oxm;
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXMS_NAME,
+ strlen(OIC_JSON_OXMS_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&doxmMap, &oxm, doxm->oxmLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Array.");
+
for (size_t i = 0; i < doxm->oxmLen; i++)
{
- cJSON_AddItemToArray (jsonOxmArray, cJSON_CreateNumber(doxm->oxm[i]));
+ cborEncoderResult = cbor_encode_int(&oxm, doxm->oxm[i]);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding oxmName Value");
}
+ cborEncoderResult = cbor_encoder_close_container(&doxmMap, &oxm);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing oxmName.");
}
//OxmSel -- Mandatory
- cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_OXM_SEL_NAME, (int)doxm->oxmSel);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OXM_SEL_NAME,
+ strlen(OIC_JSON_OXM_SEL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Sel Tag.");
+ cborEncoderResult = cbor_encode_int(&doxmMap, doxm->oxmSel);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Sel Value.");
//sct -- Mandatory
- cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_SUPPORTED_CRED_TYPE_NAME, (int)doxm->sct);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_SUPPORTED_CRED_TYPE_NAME,
+ strlen(OIC_JSON_SUPPORTED_CRED_TYPE_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Tag");
+ cborEncoderResult = cbor_encode_int(&doxmMap, doxm->sct);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Type Value.");
//Owned -- Mandatory
- cJSON_AddBoolToObject(jsonDoxm, OIC_JSON_OWNED_NAME, doxm->owned);
-
- //TODO: Need more clarification on deviceIDFormat field type.
-#if 0
- //DeviceIdFormat -- Mandatory
- cJSON_AddNumberToObject(jsonDoxm, OIC_JSON_DEVICE_ID_FORMAT_NAME, doxm->deviceIDFormat);
-#endif
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_OWNED_NAME,
+ strlen(OIC_JSON_OWNED_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owned Tag.");
+ cborEncoderResult = cbor_encode_boolean(&doxmMap, doxm->owned);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owned Value.");
//DeviceId -- Mandatory
- outLen = 0;
- b64Ret = b64Encode(doxm->deviceID.id, sizeof(doxm->deviceID.id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonDoxm, OIC_JSON_DEVICE_ID_NAME, base64Buff);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVICE_ID_NAME,
+ strlen(OIC_JSON_DEVICE_ID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
+ ret = ConvertUuidToStr(&doxm->deviceID, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
+
+ //devownerid -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVOWNERID_NAME,
+ strlen(OIC_JSON_DEVOWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owner Id Tag.");
+ ret = ConvertUuidToStr(&doxm->owner, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Owner Id Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
+
+ //ROwner -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_ROWNERID_NAME,
+ strlen(OIC_JSON_ROWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Tag.");
+ ret = ConvertUuidToStr(&doxm->rownerID, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
//DPC -- Mandatory
- cJSON_AddBoolToObject(jsonDoxm, OIC_JSON_DPC_NAME, doxm->dpc);
+ cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DPC_NAME,
+ strlen(OIC_JSON_DPC_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DPC Tag.");
+ cborEncoderResult = cbor_encode_boolean(&doxmMap, doxm->dpc);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DPC Value.");
- //Owner -- Mandatory
- outLen = 0;
- b64Ret = b64Encode(doxm->owner.id, sizeof(doxm->owner.id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonDoxm, OIC_JSON_OWNER_NAME, base64Buff);
-
- jsonStr = cJSON_PrintUnformatted(jsonRoot);
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &doxmMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing DoxmMap.");
+ if (CborNoError == cborEncoderResult)
+ {
+ *size = encoder.ptr - outPayload;
+ *payload = outPayload;
+ ret = OC_STACK_OK;
+ }
exit:
- if (jsonRoot)
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+ {
+ OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ OIC_LOG_V(DEBUG, TAG, "Doxm reallocation size : %zd.", cborLen);
+ cborEncoderResult = CborNoError;
+ ret = DoxmToCBORPayload(doxm, payload, &cborLen);
+ *size = cborLen;
+ }
+
+ if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
{
- cJSON_Delete(jsonRoot);
+ OICFree(outPayload);
+ outPayload = NULL;
+ *payload = NULL;
+ *size = 0;
+ ret = OC_STACK_ERROR;
}
- return jsonStr;
+
+ return ret;
}
-OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr)
+OCStackResult CBORPayloadToDoxm(const uint8_t *cborPayload, size_t size,
+ OicSecDoxm_t **secDoxm)
{
-
- if (NULL == jsonStr)
+ if (NULL == cborPayload || NULL == secDoxm || NULL != *secDoxm || 0 == size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
OCStackResult ret = OC_STACK_ERROR;
- OicSecDoxm_t *doxm = NULL;
- cJSON *jsonDoxm = NULL;
- cJSON *jsonObj = NULL;
+ *secDoxm = NULL;
- size_t jsonObjLen = 0;
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
+ CborParser parser;
+ CborError cborFindResult = CborNoError;
+ char* strUuid = NULL;
+ size_t len = 0;
+ CborValue doxmCbor;
- cJSON *jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
-
- jsonDoxm = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DOXM_NAME);
- VERIFY_NON_NULL(TAG, jsonDoxm, ERROR);
-
- doxm = (OicSecDoxm_t*)OICCalloc(1, sizeof(OicSecDoxm_t));
+ cbor_parser_init(cborPayload, size, 0, &parser, &doxmCbor);
+ CborValue doxmMap;
+ OicSecDoxm_t *doxm = (OicSecDoxm_t *)OICCalloc(1, sizeof(*doxm));
VERIFY_NON_NULL(TAG, doxm, ERROR);
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXM_TYPE_NAME, &doxmMap);
//OxmType -- not Mandatory
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_TYPE_NAME);
- if ((jsonObj) && (cJSON_Array == jsonObj->type))
+ if (CborNoError == cborFindResult && cbor_value_is_array(&doxmMap))
{
- doxm->oxmTypeLen = (size_t)cJSON_GetArraySize(jsonObj);
- VERIFY_SUCCESS(TAG, doxm->oxmTypeLen > 0, ERROR);
+ CborValue oxmType;
- doxm->oxmType = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(char *));
- VERIFY_NON_NULL(TAG, (doxm->oxmType), ERROR);
+ cborFindResult = cbor_value_get_array_length(&doxmMap, &doxm->oxmTypeLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxmTypeLen.")
+ VERIFY_SUCCESS(TAG, doxm->oxmTypeLen != 0, ERROR);
- for (size_t i = 0; i < doxm->oxmTypeLen ; i++)
- {
- cJSON *jsonOxmTy = cJSON_GetArrayItem(jsonObj, i);
- VERIFY_NON_NULL(TAG, jsonOxmTy, ERROR);
+ doxm->oxmType = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(*doxm->oxmType));
+ VERIFY_NON_NULL(TAG, doxm->oxmType, ERROR);
- jsonObjLen = strlen(jsonOxmTy->valuestring) + 1;
- doxm->oxmType[i] = (char*)OICMalloc(jsonObjLen);
- VERIFY_NON_NULL(TAG, doxm->oxmType[i], ERROR);
- strncpy((char *)doxm->oxmType[i], (char *)jsonOxmTy->valuestring, jsonObjLen);
+ cborFindResult = cbor_value_enter_container(&doxmMap, &oxmType);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering oxmType Array.")
+
+ int i = 0;
+ size_t len = 0;
+ while (cbor_value_is_valid(&oxmType))
+ {
+ cborFindResult = cbor_value_dup_text_string(&oxmType, &doxm->oxmType[i++],
+ &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding omxType text string.")
+ cborFindResult = cbor_value_advance(&oxmType);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing oxmType.")
}
}
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXMS_NAME, &doxmMap);
//Oxm -- not Mandatory
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_NAME);
- if (jsonObj && cJSON_Array == jsonObj->type)
+ if (CborNoError == cborFindResult && cbor_value_is_array(&doxmMap))
{
- doxm->oxmLen = (size_t)cJSON_GetArraySize(jsonObj);
- VERIFY_SUCCESS(TAG, doxm->oxmLen > 0, ERROR);
+ CborValue oxm;
+ cborFindResult = cbor_value_get_array_length(&doxmMap, &doxm->oxmLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxmName array Length.")
+ VERIFY_SUCCESS(TAG, doxm->oxmLen != 0, ERROR);
- doxm->oxm = (OicSecOxm_t*)OICCalloc(doxm->oxmLen, sizeof(OicSecOxm_t));
+ doxm->oxm = (OicSecOxm_t *)OICCalloc(doxm->oxmLen, sizeof(*doxm->oxm));
VERIFY_NON_NULL(TAG, doxm->oxm, ERROR);
- for (size_t i = 0; i < doxm->oxmLen ; i++)
+ cborFindResult = cbor_value_enter_container(&doxmMap, &oxm);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering oxmName Array.")
+
+ int i = 0;
+ while (cbor_value_is_valid(&oxm))
{
- cJSON *jsonOxm = cJSON_GetArrayItem(jsonObj, i);
- VERIFY_NON_NULL(TAG, jsonOxm, ERROR);
- doxm->oxm[i] = (OicSecOxm_t)jsonOxm->valueint;
+ cborFindResult = cbor_value_get_int(&oxm, (int *) &doxm->oxm[i++]);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding oxmName Value")
+ cborFindResult = cbor_value_advance(&oxm);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing oxmName.")
}
}
- //OxmSel -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_SEL_NAME);
- if(jsonObj)
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OXM_SEL_NAME, &doxmMap);
+ if (CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
{
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- doxm->oxmSel = (OicSecOxm_t)jsonObj->valueint;
+ cborFindResult = cbor_value_get_int(&doxmMap, (int *) &doxm->oxmSel);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Sel Name Value.")
}
else // PUT/POST JSON may not have oxmsel so set it to the gDoxm->oxmSel
{
doxm->oxmSel = gDoxm->oxmSel;
}
- //sct -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
- if(jsonObj)
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_SUPPORTED_CRED_TYPE_NAME, &doxmMap);
+ if (CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
{
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- doxm->sct = (OicSecCredType_t)jsonObj->valueint;
+ cborFindResult = cbor_value_get_int(&doxmMap, (int *) &doxm->sct);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Sct Name Value.")
}
else // PUT/POST JSON may not have sct so set it to the gDoxm->sct
{
doxm->sct = gDoxm->sct;
}
- //Owned -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNED_NAME);
- if(jsonObj)
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_OWNED_NAME, &doxmMap);
+ if (CborNoError == cborFindResult && cbor_value_is_boolean(&doxmMap))
{
- VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR);
- doxm->owned = jsonObj->valueint;
+ cborFindResult = cbor_value_get_boolean(&doxmMap, &doxm->owned);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Owned Value.")
}
else // PUT/POST JSON may not have owned so set it to the gDomx->owned
{
doxm->owned = gDoxm->owned;
}
- //DeviceId -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DEVICE_ID_NAME);
- if(jsonObj)
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_DPC_NAME, &doxmMap);
+ if (CborNoError == cborFindResult && cbor_value_is_boolean(&doxmMap))
{
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- if(cJSON_String == jsonObj->type)
- {
- //Check for empty string, in case DeviceId field has not been set yet
- if (jsonObj->valuestring[0])
- {
- outLen = 0;
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(doxm->deviceID.id)),
- ERROR);
- memcpy(doxm->deviceID.id, base64Buff, outLen);
- }
- }
+ cborFindResult = cbor_value_get_boolean(&doxmMap, &doxm->dpc);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DPC Value.")
}
- else // PUT/POST JSON will not have deviceID so set it to the gDoxm->deviceID.id
+ else // PUT/POST JSON may not have owned so set it to the gDomx->owned
{
VERIFY_NON_NULL(TAG, gDoxm, ERROR);
- memcpy((char *)doxm->deviceID.id, (char *)gDoxm->deviceID.id, sizeof(doxm->deviceID.id));
+ doxm->owned = false;
}
- //DPC -- Mandatory
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DPC_NAME);
- if(jsonObj)
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_DEVICE_ID_NAME, &doxmMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
{
- VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR);
- doxm->dpc = jsonObj->valueint;
- }
- else // PUT/POST JSON may not have owned so set it to the gDomx->dpc
- {
- if(NULL != gDoxm)
- {
- doxm->dpc = gDoxm->dpc;
- }
- else
- {
- doxm->dpc = false; // default is false
- }
+ cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
+ ret = ConvertStrToUuid(strUuid , &doxm->deviceID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ OICFree(strUuid);
+ strUuid = NULL;
}
- //Owner -- will be empty when device status is unowned.
- jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNER_NAME);
- if(true == doxm->owned)
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_DEVOWNERID_NAME, &doxmMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
{
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Owner Value.");
+ ret = ConvertStrToUuid(strUuid , &doxm->owner);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ OICFree(strUuid);
+ strUuid = NULL;
}
- if(jsonObj)
+
+ cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_ROWNERID_NAME, &doxmMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
{
- VERIFY_SUCCESS(TAG, (cJSON_String == jsonObj->type), ERROR);
- outLen = 0;
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, ((b64Ret == B64_OK) && (outLen <= sizeof(doxm->owner.id))), ERROR);
- memcpy(doxm->owner.id, base64Buff, outLen);
+ cborFindResult = cbor_value_dup_text_string(&doxmMap, &strUuid , &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ROwner Value.");
+ ret = ConvertStrToUuid(strUuid , &doxm->rownerID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ OICFree(strUuid);
+ strUuid = NULL;
}
+ *secDoxm = doxm;
ret = OC_STACK_OK;
exit:
- cJSON_Delete(jsonRoot);
- if (OC_STACK_OK != ret)
+ if (CborNoError != cborFindResult)
{
+ OIC_LOG (ERROR, TAG, "CBORPayloadToDoxm failed!!!");
DeleteDoxmBinData(doxm);
doxm = NULL;
+ *secDoxm = NULL;
+ ret = OC_STACK_ERROR;
}
-
- return doxm;
+ return ret;
}
/**
if (NULL != doxm)
{
- // Convert Doxm data into JSON for update to persistent storage
- char *jsonStr = BinToDoxmJSON(doxm);
- if (jsonStr)
+ // Convert Doxm data into CBOR for update to persistent storage
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ OCStackResult res = DoxmToCBORPayload(doxm, &payload, &size);
+ if (payload && (OC_STACK_OK == res)
+ && (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, payload, size)))
+ {
+ bRet = true;
+ }
+ OICFree(payload);
+ }
+ else
+ {
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, NULL, 0))
{
- cJSON *jsonDoxm = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- if (jsonDoxm &&
- (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_DOXM_NAME, jsonDoxm)))
- {
bRet = true;
- }
- cJSON_Delete(jsonDoxm);
}
}
ParseQueryIterInit((unsigned char*)query, &parseIter);
- while(GetNextQuery(&parseIter))
+ while (GetNextQuery(&parseIter))
{
- if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_OWNED_NAME, parseIter.attrLen) == 0)
+ if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_OWNED_NAME, parseIter.attrLen) == 0)
{
bOwnedQry = true;
- if((strncasecmp((char *)parseIter.valPos, OIC_SEC_TRUE, parseIter.valLen) == 0) &&
+ if ((strncasecmp((char *)parseIter.valPos, OIC_SEC_TRUE, parseIter.valLen) == 0) &&
(gDoxm->owned))
{
bOwnedMatch = true;
}
- else if((strncasecmp((char *)parseIter.valPos, OIC_SEC_FALSE, parseIter.valLen) == 0)
+ else if ((strncasecmp((char *)parseIter.valPos, OIC_SEC_FALSE, parseIter.valLen) == 0)
&& (!gDoxm->owned))
{
bOwnedMatch = true;
}
}
- if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_DEVICE_ID_NAME, parseIter.attrLen) == 0)
+ if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_DEVICE_ID_NAME, parseIter.attrLen) == 0)
{
bDeviceIDQry = true;
OicUuid_t subject = {.id={0}};
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
-
- b64Ret = b64Decode((char *)parseIter.valPos, parseIter.valLen, base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (B64_OK == b64Ret && outLen <= sizeof(subject.id)), ERROR);
- memcpy(subject.id, base64Buff, outLen);
- if(0 == memcmp(&gDoxm->deviceID.id, &subject.id, sizeof(gDoxm->deviceID.id)))
+ memcpy(subject.id, parseIter.valPos, parseIter.valLen);
+ if (0 == memcmp(&gDoxm->deviceID.id, &subject.id, sizeof(gDoxm->deviceID.id)))
{
bDeviceIDMatch = true;
}
}
}
-exit:
return ((bOwnedQry ? bOwnedMatch : true) && (bDeviceIDQry ? bDeviceIDMatch : true));
}
static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest * ehRequest)
{
- char* jsonStr = NULL;
OCEntityHandlerResult ehRet = OC_EH_OK;
- OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing GET request");
+ OIC_LOG(DEBUG, TAG, "Doxm EntityHandle processing GET request");
//Checking if Get request is a query.
- if(ehRequest->query)
+ if (ehRequest->query)
{
- OIC_LOG (DEBUG, TAG, "HandleDoxmGetRequest processing query");
- if(!ValidateQuery(ehRequest->query))
+ OIC_LOG(DEBUG, TAG, "HandleDoxmGetRequest processing query");
+ if (!ValidateQuery(ehRequest->query))
{
ehRet = OC_EH_ERROR;
}
}
/*
- * For GET or Valid Query request return doxm resource json payload.
+ * For GET or Valid Query request return doxm resource CBOR payload.
* For non-valid query return NULL json payload.
- * A device will 'always' have a default Doxm, so BinToDoxmJSON will
+ * A device will 'always' have a default Doxm, so DoxmToCBORPayload will
* return valid doxm resource json.
*/
+ uint8_t *payload = NULL;
+ size_t size = 0;
- jsonStr = (ehRet == OC_EH_OK) ? BinToDoxmJSON(gDoxm) : NULL;
+ if (ehRet == OC_EH_OK)
+ {
+ if (OC_STACK_OK != DoxmToCBORPayload(gDoxm, &payload, &size))
+ {
+ payload = NULL;
+ }
+ }
// Send response payload to request originator
- if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, jsonStr))
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
{
- OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDoxmGetRequest");
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleDoxmGetRequest");
}
- OICFree(jsonStr);
+ OICFree(payload);
return ehRet;
}
-static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest)
+static OCEntityHandlerResult HandleDoxmPutRequest(const OCEntityHandlerRequest * ehRequest)
{
OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing PUT request");
OCEntityHandlerResult ehRet = OC_EH_ERROR;
- OicUuid_t emptyOwner = {.id = {0}};
+ OicUuid_t emptyOwner = {.id = {0} };
/*
- * Convert JSON Doxm data into binary. This will also validate
+ * Convert CBOR Doxm data into binary. This will also validate
* the Doxm data received.
*/
- OicSecDoxm_t* newDoxm = JSONToDoxmBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
+ OicSecDoxm_t *newDoxm = NULL;
- if (newDoxm)
+ if (ehRequest->payload)
{
- // Iotivity SRM ONLY supports OIC_JUST_WORKS now
- if (OIC_JUST_WORKS == newDoxm->oxmSel)
+ uint8_t *payload = ((OCSecurityPayload *)ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload *)ehRequest->payload)->payloadSize;
+ OCStackResult res = CBORPayloadToDoxm(payload, size, &newDoxm);
+
+ if (newDoxm && OC_STACK_OK == res)
{
- if ((false == gDoxm->owned) && (false == newDoxm->owned))
+ if (OIC_JUST_WORKS == newDoxm->oxmSel)
{
- /*
- * If current state of the device is un-owned, enable
- * anonymous ECDH cipher in tinyDTLS so that Provisioning
- * tool can initiate JUST_WORKS ownership transfer process.
- */
- if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
+ if ((false == gDoxm->owned) && (false == newDoxm->owned))
{
- OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite");
+ /*
+ * If current state of the device is un-owned, enable
+ * anonymous ECDH cipher in tinyDTLS so that Provisioning
+ * tool can initiate JUST_WORKS ownership transfer process.
+ */
+ if (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
+ {
+ OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite");
#ifdef __WITH_DTLS__
- ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
+ ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
#endif //__WITH_DTLS__
- goto exit;
- }
- else
- {
-#ifdef __WITH_DTLS__
- //Save the owner's UUID to derive owner credential
- memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
-
-// OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
-// //Generating OwnerPSK
-// OIC_LOG (INFO, TAG, "Doxm EntityHandle generating OwnerPSK");
-// //Generate new credential for provisioning tool
-// ehRet = AddOwnerPSK((CAEndpoint_t *)&request->devAddr, newDoxm,
-// (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS));
-// VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
-
- // Update new state in persistent storage
- if (true == UpdatePersistentStorage(gDoxm))
- {
- ehRet = OC_EH_OK;
+ goto exit;
}
else
{
- OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
- ehRet = OC_EH_ERROR;
- }
-
- /*
- * Disable anonymous ECDH cipher in tinyDTLS since device is now
- * in owned state.
- */
- CAResult_t caRes = CA_STATUS_OK;
- caRes = CAEnableAnonECDHCipherSuite(false);
- VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
- OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
+#ifdef __WITH_DTLS__
+ //Save the owner's UUID to derive owner credential
+ memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+
+ // Update new state in persistent storage
+ if (true == UpdatePersistentStorage(gDoxm))
+ {
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
+ }
+
+ /*
+ * Disable anonymous ECDH cipher in tinyDTLS since device is now
+ * in owned state.
+ */
+ CAResult_t caRes = CA_STATUS_OK;
+ caRes = CAEnableAnonECDHCipherSuite(false);
+ VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
+ OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
#ifdef __WITH_X509__
#define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE
- CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
+ CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
#endif //__WITH_X509__
#endif //__WITH_DTLS__
+ }
}
}
- }
- else if(OIC_RANDOM_DEVICE_PIN == newDoxm->oxmSel)
- {
- if ((false == gDoxm->owned) && (false == newDoxm->owned))
+ else if (OIC_RANDOM_DEVICE_PIN == newDoxm->oxmSel)
{
- /*
- * If current state of the device is un-owned, enable
- * anonymous ECDH cipher in tinyDTLS so that Provisioning
- * tool can initiate JUST_WORKS ownership transfer process.
- */
- if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
+ if ((false == gDoxm->owned) && (false == newDoxm->owned))
{
- gDoxm->oxmSel = newDoxm->oxmSel;
- //Update new state in persistent storage
- if((UpdatePersistentStorage(gDoxm) == true))
- {
- ehRet = OC_EH_OK;
- }
- else
+ /*
+ * If current state of the device is un-owned, enable
+ * anonymous ECDH cipher in tinyDTLS so that Provisioning
+ * tool can initiate JUST_WORKS ownership transfer process.
+ */
+ if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
{
- OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage");
- ehRet = OC_EH_ERROR;
- }
+ gDoxm->oxmSel = newDoxm->oxmSel;
+ //Update new state in persistent storage
+ if ((UpdatePersistentStorage(gDoxm) == true))
+ {
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
+ }
#ifdef __WITH_DTLS__
- CAResult_t caRes = CA_STATUS_OK;
+ CAResult_t caRes = CA_STATUS_OK;
- caRes = CAEnableAnonECDHCipherSuite(false);
- VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
- OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
-
- caRes = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
- VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
-
- char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,};
- if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1))
- {
- //Set the device id to derive temporal PSK
- SetUuidForRandomPinOxm(&gDoxm->deviceID);
+ caRes = CAEnableAnonECDHCipherSuite(false);
+ VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
+ OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
- /**
- * Since PSK will be used directly by DTLS layer while PIN based ownership transfer,
- * Credential should not be saved into SVR.
- * For this reason, use a temporary get_psk_info callback to random PIN OxM.
- */
- caRes = CARegisterDTLSCredentialsHandler(GetDtlsPskForRandomPinOxm);
+ caRes = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
- ehRet = OC_EH_OK;
+
+ char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,};
+ if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1))
+ {
+ //Set the device id to derive temporal PSK
+ SetUuidForRandomPinOxm(&gDoxm->deviceID);
+
+ /**
+ * Since PSK will be used directly by DTLS layer while PIN based ownership transfer,
+ * Credential should not be saved into SVR.
+ * For this reason, use a temporary get_psk_info callback to random PIN OxM.
+ */
+ caRes = CARegisterDTLSCredentialsHandler(GetDtlsPskForRandomPinOxm);
+ VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to generate random PIN");
+ ehRet = OC_EH_ERROR;
+ }
+#endif //__WITH_DTLS__
}
else
{
- OIC_LOG(ERROR, TAG, "Failed to generate random PIN");
- ehRet = OC_EH_ERROR;
+#ifdef __WITH_DTLS__
+ //Save the owner's UUID to derive owner credential
+ memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+
+ //Update new state in persistent storage
+ if (UpdatePersistentStorage(gDoxm) == true)
+ {
+ ehRet = OC_EH_OK;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
+ ehRet = OC_EH_ERROR;
+ }
+#endif
}
-#endif //__WITH_DTLS__
}
- else
+ }
+
+ /*
+ * When current state of the device is un-owned and Provisioning
+ * Tool is attempting to change the state to 'Owned' with a
+ * qualified value for the field 'Owner'
+ */
+ if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
+ (memcmp(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)) == 0))
+ {
+ //Change the SVR's resource owner as owner device.
+ OCStackResult ownerRes = SetAclRownerId(&gDoxm->owner);
+ if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
{
-#ifdef __WITH_DTLS__
- //Save the owner's UUID to derive owner credential
- memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
+ ehRet = OC_EH_ERROR;
+ goto exit;
+ }
+ ownerRes = SetAmaclRownerId(&gDoxm->owner);
+ if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
+ {
+ ehRet = OC_EH_ERROR;
+ goto exit;
+ }
+ ownerRes = SetCredRownerId(&gDoxm->owner);
+ if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
+ {
+ ehRet = OC_EH_ERROR;
+ goto exit;
+ }
+ ownerRes = SetPstatRownerId(&gDoxm->owner);
+ if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
+ {
+ ehRet = OC_EH_ERROR;
+ goto exit;
+ }
+ ownerRes = SetDpairingRownerId(&gDoxm->owner);
+ if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
+ {
+ ehRet = OC_EH_ERROR;
+ goto exit;
+ }
+ ownerRes = SetPconfRownerId(&gDoxm->owner);
+ if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
+ {
+ ehRet = OC_EH_ERROR;
+ goto exit;
+ }
- //Update new state in persistent storage
- if((UpdatePersistentStorage(gDoxm) == true))
+ gDoxm->owned = true;
+ memcpy(&gDoxm->rownerID, &gDoxm->owner, sizeof(OicUuid_t));
+
+ // Update new state in persistent storage
+ if (UpdatePersistentStorage(gDoxm))
+ {
+ //Update default ACL of security resource to prevent anonymous user access.
+ if(OC_STACK_OK == UpdateDefaultSecProvACL())
{
ehRet = OC_EH_OK;
}
else
{
- OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
+ OIC_LOG(ERROR, TAG, "Failed to remove default ACL for security provisioning");
ehRet = OC_EH_ERROR;
}
-#endif
- }
- }
- }
-
- /*
- * When current state of the device is un-owned and Provisioning
- * Tool is attempting to change the state to 'Owned' with a
- * qualified value for the field 'Owner'
- */
- if ((false == gDoxm->owned) && (true == newDoxm->owned) &&
- (memcmp(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)) == 0))
- {
- gDoxm->owned = true;
- // Update new state in persistent storage
- if (UpdatePersistentStorage(gDoxm))
- {
- //Update default ACL of security resource to prevent anonymous user access.
- if(OC_STACK_OK == UpdateDefaultSecProvACL())
- {
- ehRet = OC_EH_OK;
}
else
{
- OIC_LOG(ERROR, TAG, "Failed to remove default ACL for security provisioning");
+ OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
ehRet = OC_EH_ERROR;
}
}
- else
- {
- OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
- ehRet = OC_EH_ERROR;
- }
}
}
}
//Send payload to request originator
- if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
{
- OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest");
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleDoxmPostRequest");
}
DeleteDoxmBinData(newDoxm);
return ehRet;
}
-/*
- * This internal method is the entity handler for DOXM resources.
- */
-OCEntityHandlerResult DoxmEntityHandler (OCEntityHandlerFlag flag,
+OCEntityHandlerResult DoxmEntityHandler(OCEntityHandlerFlag flag,
OCEntityHandlerRequest * ehRequest,
void* callbackParam)
{
return ehRet;
}
-
if (flag & OC_REQUEST_FLAG)
{
- OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
+ OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
+
switch (ehRequest->method)
{
case OC_REST_GET:
default:
ehRet = OC_EH_ERROR;
- SendSRMResponse(ehRequest, ehRet, NULL);
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
break;
}
}
return ehRet;
}
-/*
- * This internal method is used to create '/oic/sec/doxm' resource.
- */
OCStackResult CreateDoxmResource()
{
- OCStackResult ret;
-
- ret = OCCreateResource(&gDoxmHandle,
- OIC_RSRC_TYPE_SEC_DOXM,
- OIC_MI_DEF,
- OIC_RSRC_DOXM_URI,
- DoxmEntityHandler,
- NULL,
- OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
+ OCStackResult ret = OCCreateResource(&gDoxmHandle,
+ OIC_RSRC_TYPE_SEC_DOXM,
+ OIC_MI_DEF,
+ OIC_RSRC_DOXM_URI,
+ DoxmEntityHandler,
+ NULL,
+ OC_OBSERVABLE | OC_SECURE |
+ OC_EXPLICIT_DISCOVERABLE);
if (OC_STACK_OK != ret)
{
* Checks if DeviceID is generated during provisioning for the new device.
* If DeviceID is NULL then generates the new DeviceID.
* Once DeviceID is assigned to the device it does not change for the lifetime of the device.
- *
*/
static OCStackResult CheckDeviceID()
{
}
ret = OC_STACK_OK;
- if (UpdatePersistentStorage(gDoxm))
+ if (!UpdatePersistentStorage(gDoxm))
{
//TODO: After registering PSI handler in all samples, do ret = OC_STACK_OK here.
OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
/**
* Get the default value.
- * @retval the gDefaultDoxm pointer;
+ *
+ * @return the default value of doxm, @ref OicSecDoxm_t.
*/
static OicSecDoxm_t* GetDoxmDefault()
{
- OIC_LOG (DEBUG, TAG, "GetDoxmToDefault");
+ OIC_LOG(DEBUG, TAG, "GetDoxmToDefault");
return &gDefaultDoxm;
}
-/**
- * This method is used by SRM to retrieve DOXM resource data.
- *
- * @retval reference to @ref OicSecDoxm_t, binary format of Doxm resource data
- */
const OicSecDoxm_t* GetDoxmResourceData()
{
return gDoxm;
}
-/**
- * Initialize DOXM resource by loading data from persistent storage.
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult InitDoxmResource()
{
OCStackResult ret = OC_STACK_ERROR;
//Read DOXM resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
- if(jsonSVRDatabase)
+ uint8_t *data = NULL;
+ size_t size = 0;
+ ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_DOXM_NAME, &data, &size);
+ // If database read failed
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
+ if (data)
{
- //Convert JSON DOXM into binary format
- gDoxm = JSONToDoxmBin(jsonSVRDatabase);
+ // Read DOXM resource from PS
+ ret = CBORPayloadToDoxm(data, size, &gDoxm);
}
/*
* If SVR database in persistent storage got corrupted or
* is not available for some reason, a default doxm is created
* which allows user to initiate doxm provisioning again.
*/
- if(!jsonSVRDatabase || !gDoxm)
+ if ((OC_STACK_OK != ret) || !data || !gDoxm)
{
gDoxm = GetDoxmDefault();
}
ret = CheckDeviceID();
if (ret == OC_STACK_OK)
{
+ OIC_LOG_V(DEBUG, TAG, "Initial Doxm Owned = %d", gDoxm->owned);
//Instantiate 'oic.sec.doxm'
ret = CreateDoxmResource();
}
{
OIC_LOG (ERROR, TAG, "CheckDeviceID failed");
}
- OICFree(jsonSVRDatabase);
+ OICFree(data);
return ret;
}
-/**
- * Perform cleanup for DOXM resources.
- *
- * @return
- * OC_STACK_OK - no error
- * OC_STACK_ERROR - stack process error
- *
- */
OCStackResult DeInitDoxmResource()
{
OCStackResult ret = OCDeleteResource(gDoxmHandle);
- if(gDoxm != &gDefaultDoxm)
+ if (gDoxm != &gDefaultDoxm)
{
DeleteDoxmBinData(gDoxm);
}
gDoxm = NULL;
- if(OC_STACK_OK == ret)
+ if (OC_STACK_OK == ret)
{
return OC_STACK_OK;
}
}
}
-
-/**
- * This method returns the SRM device ID for this device.
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult GetDoxmDeviceID(OicUuid_t *deviceID)
{
- if(deviceID && gDoxm)
+ if (deviceID && gDoxm)
{
*deviceID = gDoxm->deviceID;
return OC_STACK_OK;
return OC_STACK_ERROR;
}
-/**
- * @brief Gets the OicUuid_t value for the owner of this device.
- *
- * @return OC_STACK_OK if devOwner is a valid UUID, otherwise OC_STACK_ERROR.
- */
-OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner)
+OCStackResult GetDoxmDevOwnerId(OicUuid_t *devownerid)
{
OCStackResult retVal = OC_STACK_ERROR;
- if(gDoxm)
+ if (gDoxm)
{
- if(gDoxm->owned) {
- *devOwner = gDoxm->owner; // TODO change to devOwner when available
+ OIC_LOG_V(DEBUG, TAG, "GetDoxmDevOwnerId(): gDoxm owned = %d.", \
+ gDoxm->owned);
+ if (gDoxm->owned)
+ {
+ *devownerid = gDoxm->owner;
retVal = OC_STACK_OK;
}
}
return retVal;
}
+OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid)
+{
+ OCStackResult retVal = OC_STACK_ERROR;
+ if (gDoxm)
+ {
+ if( gDoxm->owned )
+ {
+ *rowneruuid = gDoxm->rownerID;
+ retVal = OC_STACK_OK;
+ }
+ }
+ return retVal;
+}
+
/**
* Function to restore doxm resurce to initial status.
* This function will use in case of error while ownership transfer
-/* *****************************************************************\r
- *\r
- * Copyright 2016 Samsung Electronics All Rights Reserved.\r
- *\r
- *\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * *****************************************************************/\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include "ocstack.h"\r
-#include "logger.h"\r
-#include "oic_malloc.h"\r
-#include "oic_string.h"\r
-#include "cJSON.h"\r
-#include "base64.h"\r
-#include "resourcemanager.h"\r
-#include "dpairingresource.h"\r
-#include "psinterface.h"\r
-#include "utlist.h"\r
-#include "srmresourcestrings.h"\r
-#include "cainterface.h"\r
-#include "doxmresource.h"\r
-#include "pconfresource.h"\r
-#include "credresource.h"\r
-#include "aclresource.h"\r
-#include "srmutility.h"\r
-#include "ocserverrequest.h"\r
-#include <stdlib.h>\r
-#ifdef WITH_ARDUINO\r
-#include <string.h>\r
-#else\r
-#include <strings.h>\r
-#endif\r
-\r
-#ifdef __WITH_DTLS__\r
-#include "global.h"\r
-#endif\r
-\r
-#define TAG "SRM-DPAIRING"\r
-\r
-\r
-static OicSecDpairing_t *gDpair = NULL;\r
-static OCResourceHandle gDpairHandle = NULL;\r
-static OicSecDpairing_t gDefaultDpair =\r
-{\r
- PRM_NOT_ALLOWED, /* OicSecPrm_t spm */\r
- {.id = {0}}, /* OicUuid_t pdeviceID */\r
- {.id = {0}}, /* OicUuid_t rowner */\r
-};\r
-\r
-void DeleteDpairingBinData(OicSecDpairing_t* dpair)\r
-{\r
- if (dpair)\r
- {\r
- //Clean dpairing itself\r
- OICFree(dpair);\r
- }\r
-}\r
-\r
-/**\r
- * Get the default value.\r
- * @retval the gDefaultDpair pointer;\r
- */\r
-static OicSecDpairing_t* GetDpairingDefault()\r
-{\r
- OIC_LOG (DEBUG, TAG, "GetDpairingDefault");\r
-\r
- return &gDefaultDpair;\r
-}\r
-\r
-/**\r
- * This method is used by SRM to retrieve Dpairing resource data..\r
- */\r
-void SetDpairingResourceOwner(OicUuid_t *rowner)\r
-{\r
- OIC_LOG (DEBUG, TAG, "SetDpairingResourceOwner");\r
- if (gDpair)\r
- {\r
- memcpy(&gDpair->rowner, rowner, sizeof(OicUuid_t));\r
- }\r
-}\r
-\r
-#ifdef __WITH_DTLS__\r
-/**\r
- * Function to save PairingPSK.\r
- *\r
- * @param[in] endpoint current endpoint.\r
- * @param[in] peerDevID peer device indentitiy.\r
- * @param[in] isPairingServer indicate if it generates PairingPSK for server or client.\r
- *\r
- * @return OC_STACK_OK on success\r
- */\r
-OCStackResult SavePairingPSK(OCDevAddr *endpoint,\r
- OicUuid_t *peerDevID, OicUuid_t *owner, bool isPairingServer)\r
-{\r
- OIC_LOG(DEBUG, TAG, "IN SavePairingPSK");\r
-\r
- if(NULL == endpoint || NULL == peerDevID || NULL == owner)\r
- {\r
- OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);\r
- return OC_STACK_INVALID_PARAM;\r
- }\r
-\r
- OCStackResult res = OC_STACK_ERROR;\r
-\r
- OicUuid_t ptDeviceID = {.id={0}};\r
- if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))\r
- {\r
- OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");\r
- return res;\r
- }\r
-\r
- uint8_t pairingPSK[OWNER_PSK_LENGTH_128] = {0};\r
-\r
- //Generating PairingPSK using OwnerPSK scheme\r
- CAResult_t pskRet = CAGenerateOwnerPSK((const CAEndpoint_t *)endpoint,\r
- (uint8_t *)OIC_RSRC_TYPE_SEC_DPAIRING,\r
- strlen(OIC_RSRC_TYPE_SEC_DPAIRING),\r
- (isPairingServer ? ptDeviceID.id : peerDevID->id), sizeof(OicUuid_t), // server\r
- (isPairingServer ? peerDevID->id : ptDeviceID.id), sizeof(OicUuid_t), // client\r
- pairingPSK, OWNER_PSK_LENGTH_128);\r
-\r
- if (CA_STATUS_OK == pskRet)\r
- {\r
- OIC_LOG(INFO, TAG, "pairingPSK dump:\n");\r
- OIC_LOG_BUFFER(INFO, TAG, pairingPSK, OWNER_PSK_LENGTH_128);\r
- //Generating new credential for direct-pairing client\r
- size_t ownLen = 1;\r
- uint32_t outLen = 0;\r
-\r
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(pairingPSK)) + 1] = {};\r
- B64Result b64Ret = b64Encode(pairingPSK, sizeof(pairingPSK), base64Buff, sizeof(base64Buff),\r
- &outLen);\r
- VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);\r
-\r
- OicSecCred_t *cred = GenerateCredential(peerDevID,\r
- SYMMETRIC_PAIR_WISE_KEY, NULL,\r
- base64Buff, ownLen, owner);\r
- VERIFY_NON_NULL(TAG, cred, ERROR);\r
-\r
- res = AddCredential(cred);\r
- if(res != OC_STACK_OK)\r
- {\r
- DeleteCredList(cred);\r
- return res;\r
- }\r
- }\r
- else\r
- {\r
- OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");\r
- }\r
-\r
- OIC_LOG(DEBUG, TAG, "OUT SavePairingPSK");\r
-exit:\r
- return res;\r
-}\r
-#endif // __WITH_DTLS__\r
-\r
-/*\r
- * This internal method converts DPairing data into JSON format.\r
- * Does not error-check here, but check it in caller\r
- *\r
- * Note: Caller needs to invoke 'free' when finished done using\r
- * return string.\r
- */\r
-char * BinToDpairingJSON(const OicSecDpairing_t * dpair)\r
-{\r
- OIC_LOG(DEBUG, TAG, "BinToDpairingJSON() IN");\r
-\r
- if (NULL == dpair)\r
- {\r
- return NULL;\r
- }\r
-\r
- char *jsonStr = NULL;\r
- cJSON *jsonDpair = NULL;\r
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};\r
- uint32_t outLen = 0;\r
- B64Result b64Ret = B64_OK;\r
-\r
- cJSON *jsonRoot = cJSON_CreateObject();\r
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);\r
-\r
- jsonDpair = cJSON_CreateObject();\r
- VERIFY_NON_NULL(TAG, jsonDpair, ERROR);\r
- cJSON_AddItemToObject(jsonRoot, OIC_JSON_DPAIRING_NAME, jsonDpair );\r
-\r
- //SPM -- Mandatory\r
- if(PRM_RANDOM_PIN >= dpair->spm) // don't need to check "PRM_NOT_ALLOWED <= dpair->spm" because of always true\r
- {\r
- cJSON_AddNumberToObject(jsonDpair, OIC_JSON_SPM_NAME, (int)dpair->spm);\r
- }\r
-\r
- //PDeviceID -- Mandatory\r
- //There may not be paired devices if it did not be received pairing request\r
- if ('\0' != (char)dpair->pdeviceID.id[0])\r
- {\r
- outLen = 0;\r
- b64Ret = b64Encode(dpair->pdeviceID.id, sizeof(dpair->pdeviceID.id), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);\r
- cJSON_AddStringToObject(jsonDpair, OIC_JSON_PDEVICE_ID_NAME, base64Buff);\r
- }\r
-\r
- //ROwner -- Mandatory\r
- if ('\0' != (char)dpair->rowner.id[0])\r
- {\r
- outLen = 0;\r
- b64Ret = b64Encode(dpair->rowner.id, sizeof(dpair->rowner.id), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);\r
- cJSON_AddStringToObject(jsonDpair, OIC_JSON_ROWNER_NAME, base64Buff);\r
- }\r
-\r
-\r
- jsonStr = cJSON_PrintUnformatted(jsonRoot);\r
-\r
-exit:\r
- if (jsonRoot)\r
- {\r
- cJSON_Delete(jsonRoot);\r
- }\r
- return jsonStr;\r
-}\r
-\r
-/*\r
- * This internal method converts JSON Dpairing into binary Dpairing.\r
- * Does not error-check here, but check it in caller\r
- */\r
-OicSecDpairing_t* JSONToDpairingBin(const char * jsonStr)\r
-{\r
- OIC_LOG(DEBUG, TAG, "JSONToDpairingBin() IN");\r
-\r
- OCStackResult ret = OC_STACK_ERROR;\r
- OicSecDpairing_t *dpair = NULL;\r
- cJSON *jsonRoot = NULL;\r
- cJSON *jsonDpair = NULL;\r
- cJSON *jsonObj = NULL;\r
-\r
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};\r
- uint32_t outLen = 0;\r
- B64Result b64Ret = B64_OK;\r
-\r
-\r
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);\r
-\r
- jsonRoot = cJSON_Parse(jsonStr);\r
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);\r
-\r
- jsonDpair = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DPAIRING_NAME);\r
- VERIFY_NON_NULL(TAG, jsonDpair, ERROR);\r
-\r
- dpair = (OicSecDpairing_t*)OICCalloc(1, sizeof(OicSecDpairing_t));\r
- VERIFY_NON_NULL(TAG, dpair, ERROR);\r
-\r
- //SPM -- Mandatory\r
- jsonObj = cJSON_GetObjectItem(jsonDpair, OIC_JSON_SPM_NAME);\r
- if (jsonObj && cJSON_Number == jsonObj->type)\r
- {\r
- dpair->spm = (OicSecPrm_t)jsonObj->valueint;\r
- OIC_LOG_V (DEBUG, TAG, "jsonObj->valueint = %d", jsonObj->valueint);\r
- OIC_LOG_V (DEBUG, TAG, "dpair->spm = %d", dpair->spm);\r
-\r
- // don't need to check "PRM_NOT_ALLOWED <= dpair->spm" because of always true\r
- VERIFY_SUCCESS(TAG, (PRM_RANDOM_PIN >= dpair->spm), ERROR);\r
- }\r
- else\r
- {\r
- dpair->spm = PRM_NOT_ALLOWED;\r
- }\r
-\r
- //PDeviceId -- Mandatory\r
- outLen = 0;\r
- jsonObj = cJSON_GetObjectItem(jsonDpair, OIC_JSON_PDEVICE_ID_NAME);\r
- if (jsonObj && cJSON_String == jsonObj->type)\r
- {\r
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(dpair->pdeviceID.id)), ERROR);\r
- memcpy(dpair->pdeviceID.id, base64Buff, outLen);\r
- }\r
- else\r
- {\r
- memset(&dpair->pdeviceID, 0, sizeof(OicUuid_t));\r
- }\r
-\r
- // ROwner -- Mandatory\r
- outLen = 0;\r
- jsonObj = cJSON_GetObjectItem(jsonDpair, OIC_JSON_ROWNER_NAME);\r
- if (jsonObj && cJSON_String == jsonObj->type)\r
- {\r
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(dpair->rowner.id)), ERROR);\r
- memcpy(dpair->rowner.id, base64Buff, outLen);\r
- }\r
- else\r
- {\r
- memset(&dpair->rowner, 0, sizeof(OicUuid_t));\r
- }\r
-\r
- ret = OC_STACK_OK;\r
-\r
-exit:\r
- cJSON_Delete(jsonRoot);\r
- if (OC_STACK_OK != ret)\r
- {\r
- DeleteDpairingBinData(dpair);\r
- dpair = NULL;\r
- }\r
-\r
- OIC_LOG(DEBUG, TAG, "JSONToDpairingBin() OUT");\r
- return dpair;\r
-}\r
-\r
-/**\r
- * Function to handle the handshake result in Direct-Pairing.\r
- * This function will be invoked after DTLS handshake\r
- * @param endPoint [IN] The remote endpoint.\r
- * @param errorInfo [IN] Error information from the endpoint.\r
- * @return NONE\r
- */\r
-void DPairingDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)\r
-{\r
- OIC_LOG_V(INFO, TAG, "IN DPairingDTLSHandshakeCB");\r
-\r
- if(gDpair && endpoint && info)\r
- {\r
- OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",\r
- endpoint->addr, endpoint->port, info->result);\r
-\r
- if(CA_STATUS_OK == info->result)\r
- {\r
- OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Connection success.");\r
- }\r
- else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)\r
- {\r
- OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Authentication failed");\r
-\r
- }\r
-\r
-#ifdef __WITH_DTLS__\r
- CARegisterDTLSHandshakeCallback(NULL);\r
-#endif // __WITH_DTLS__\r
-\r
- // delete temporary key\r
- RemoveCredential(&gDpair->pdeviceID);\r
- }\r
-\r
- OIC_LOG_V(INFO, TAG, "OUT DPairingDTLSHandshakeCB");\r
-}\r
-\r
-static OCEntityHandlerResult HandleDpairingPostRequest (const OCEntityHandlerRequest * ehRequest)\r
-{\r
- OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing POST request");\r
- OCEntityHandlerResult ehRet = OC_EH_ERROR;\r
- OicSecDpairing_t* newDpair = NULL;\r
-\r
- const OicSecPconf_t *pconf = GetPconfResourceData();\r
- if (true == pconf->edp)\r
- {\r
- // Convert JSON DPAIRING data into binary. This will also validate the DPAIRING data received.\r
- newDpair = JSONToDpairingBin(((OCSecurityPayload*)ehRequest->payload)->securityData);\r
- }\r
- else\r
- {\r
- OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled");\r
- ehRet = OC_EH_ERROR;\r
- }\r
-\r
- if (newDpair && false == IsPairedDevice(&newDpair->pdeviceID))\r
- {\r
- // Check if valid Post request\r
- bool prmMached = false;\r
- for (size_t i=0; i<pconf->prmLen; i++)\r
- {\r
- if (newDpair->spm == pconf->prm[i])\r
- {\r
- prmMached = true;\r
- break;\r
- }\r
- }\r
- OIC_LOG_V(DEBUG, TAG, "Parsed spm is %s", prmMached ? "valid" : "invalid, send error response");\r
-\r
- // Update local Dpairing with new Dpairing & prepare dtls session\r
- if (prmMached && '\0' != (char)newDpair->pdeviceID.id[0])\r
- {\r
- if(!gDpair)\r
- {\r
- gDpair = GetDpairingDefault();\r
- }\r
- gDpair->spm = newDpair->spm;\r
- memcpy(&gDpair->pdeviceID, &newDpair->pdeviceID, sizeof(OicUuid_t));\r
- memcpy(&gDpair->rowner, &pconf->rowner, sizeof(OicUuid_t));\r
-\r
-#ifdef __WITH_DTLS__\r
- // Add temporary psk\r
- OCStackResult res;\r
- OicUuid_t subjectId = {.id={0}};\r
- res = AddTmpPskWithPIN(&gDpair->pdeviceID,\r
- SYMMETRIC_PAIR_WISE_KEY,\r
- (char*)pconf->pin.val, DP_PIN_LENGTH,\r
- 1, &gDpair->rowner, &subjectId);\r
- if(res != OC_STACK_OK ||\r
- memcmp(&gDpair->pdeviceID, &subjectId, sizeof(OicUuid_t)))\r
- {\r
- OIC_LOG_V(ERROR, TAG, "Failed to save the temporal PSK : %d", res);\r
- goto exit;\r
- }\r
-\r
- // Prepare to establish a secure channel with Pin-based PSK cipher suite\r
- if (CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false) ||\r
- CA_STATUS_OK != CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))\r
- {\r
- OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");\r
- goto exit;\r
- }\r
-\r
- if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DPairingDTLSHandshakeCB))\r
- {\r
- OIC_LOG(WARNING, TAG, "DirectPairingHandler : Failed to register DTLS handshake callback.");\r
- goto exit;\r
- }\r
-#endif // __WITH_DTLS__\r
-\r
- // should be lock /oic/sec/dpairing resource if Direct-Pairing starts normally ?\r
- OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource created");\r
-\r
- ehRet = OC_EH_RESOURCE_CREATED;\r
- }\r
- else\r
- {\r
- OIC_LOG(ERROR, TAG, "Error in request check");\r
- }\r
- }\r
-\r
-\r
-#ifdef __WITH_DTLS__\r
-exit:\r
-#endif // __WITH_DTLS__\r
-\r
- if (OC_EH_ERROR == ehRet && gDpair)\r
- {\r
- RemoveCredential(&gDpair->pdeviceID);\r
- gDpair = NULL;\r
- }\r
-\r
- // Send payload to request originator\r
- if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))\r
- {\r
- OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPostRequest");\r
- }\r
-\r
- DeleteDpairingBinData(newDpair);\r
- OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);\r
- return ehRet;\r
-}\r
-\r
-static OCEntityHandlerResult HandleDpairingPutRequest (const OCEntityHandlerRequest * ehRequest)\r
-{\r
- OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing PUT request (Comfirmation)");\r
-\r
- OCEntityHandlerResult ehRet = OC_EH_ERROR;\r
- OicSecDpairing_t* newDpair = NULL;\r
-\r
- const OicSecPconf_t *pconf = GetPconfResourceData();\r
- if (true == pconf->edp)\r
- {\r
- // Convert JSON DPAIRING data into binary. This will also validate the DPAIRING data received.\r
- newDpair = JSONToDpairingBin(((OCSecurityPayload*)ehRequest->payload)->securityData);\r
- }\r
- else\r
- {\r
- OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled");\r
- ehRet = OC_EH_ERROR;\r
- }\r
-\r
- if (gDpair && newDpair)\r
- {\r
- OIC_LOG(DEBUG, TAG, "Received direct-pairing finalization request");\r
-\r
- // Check if valid Put request\r
- VERIFY_SUCCESS(TAG, PRM_NOT_ALLOWED == newDpair->spm, ERROR);\r
-\r
- const OicSecPconf_t *pconf = GetPconfResourceData();\r
- VERIFY_NON_NULL(TAG, pconf, ERROR);\r
-\r
-#ifdef __WITH_DTLS__\r
- OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;\r
- VERIFY_SUCCESS(TAG, (request->devAddr.flags | OC_FLAG_SECURE), ERROR);\r
-\r
- //Generate new credential\r
- OIC_LOG_V(INFO, TAG, "SavePairingPSK for %s(%d)", request->devAddr.addr, request->devAddr.port);\r
- OCStackResult res = SavePairingPSK(&request->devAddr, &newDpair->pdeviceID,\r
- (OicUuid_t *)&pconf->rowner, true);\r
- VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);\r
-#endif //__WITH_DTLS__\r
-\r
- //Generate new acl\r
- OicSecPdAcl_t *pdAcl;\r
- LL_FOREACH(pconf->pdacls, pdAcl)\r
- {\r
- OicSecAcl_t acl;\r
- memset(&acl, 0, sizeof(OicSecAcl_t));\r
- memcpy(&acl.subject, &gDpair->pdeviceID, sizeof(OicUuid_t));\r
- acl.resources = pdAcl->resources;\r
- acl.resourcesLen = pdAcl->resourcesLen;\r
- acl.owners = (OicUuid_t*)&pconf->rowner;\r
- acl.ownersLen = 1;\r
- acl.permission = pdAcl->permission;\r
- acl.periods = pdAcl->periods;\r
- acl.recurrences = pdAcl->recurrences;\r
- acl.prdRecrLen = pdAcl->prdRecrLen;\r
-\r
- char* aclJson = BinToAclJSON(&acl);\r
- if (aclJson)\r
- {\r
- InstallNewACL(aclJson);\r
- OICFree(aclJson);\r
- }\r
- }\r
-\r
- //update pconf device list\r
- AddPairedDevice(&newDpair->pdeviceID);\r
-\r
- //Initialize dpairing resource\r
- gDpair = NULL;\r
-\r
- OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource updated, direct-pairing finalization success");\r
- ehRet = OC_EH_OK;\r
- }\r
-\r
-exit:\r
-\r
- //Send payload to request originator\r
- if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))\r
- {\r
- OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPutRequest");\r
- }\r
-\r
- DeleteDpairingBinData(newDpair);\r
- OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);\r
- return ehRet;\r
-}\r
-/*\r
- * This internal method is the entity handler for Dpairing resources and\r
- * will handle REST request (GET/POST) for them.\r
- */\r
-OCEntityHandlerResult DpairingEntityHandler (OCEntityHandlerFlag flag,\r
- OCEntityHandlerRequest * ehRequest,\r
- void* callbackParameter)\r
-{\r
- OIC_LOG(DEBUG, TAG, "Received request DpairingEntityHandler");\r
- (void)callbackParameter;\r
- OCEntityHandlerResult ehRet = OC_EH_ERROR;\r
-\r
- if (!ehRequest)\r
- {\r
- return ehRet;\r
- }\r
-\r
- if (flag & OC_REQUEST_FLAG)\r
- {\r
- OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");\r
- switch (ehRequest->method)\r
- {\r
- case OC_REST_GET:\r
- break;\r
-\r
- case OC_REST_POST:\r
- ehRet = HandleDpairingPostRequest(ehRequest);\r
- break;\r
-\r
- case OC_REST_PUT:\r
- ehRet = HandleDpairingPutRequest(ehRequest);\r
- break;\r
-\r
- case OC_REST_DELETE:\r
- break;\r
-\r
- default:\r
- ehRet = OC_EH_ERROR;\r
- SendSRMResponse(ehRequest, ehRet, NULL);\r
- }\r
- }\r
-\r
- return ehRet;\r
-}\r
-\r
-/*\r
- * This internal method is used to create '/oic/sec/dpairing' resource.\r
- */\r
-OCStackResult CreateDpairingResource()\r
-{\r
- OCStackResult ret;\r
-\r
- ret = OCCreateResource(&gDpairHandle,\r
- OIC_RSRC_TYPE_SEC_DPAIRING,\r
- OIC_MI_DEF,\r
- OIC_RSRC_DPAIRING_URI,\r
- DpairingEntityHandler,\r
- NULL,\r
- OC_SECURE | OC_EXPLICIT_DISCOVERABLE);\r
-\r
- if (OC_STACK_OK != ret)\r
- {\r
- OIC_LOG (ERROR, TAG, "Unable to instantiate Dpairing resource");\r
- DeInitDpairingResource();\r
- }\r
- return ret;\r
-}\r
-\r
-/**\r
- * Initialize Dpairing resource by loading data from persistent storage.\r
- *\r
- * @retval OC_STACK_OK for Success, otherwise some error value\r
- */\r
-OCStackResult InitDpairingResource()\r
-{\r
- OCStackResult ret = OC_STACK_ERROR;\r
-\r
- // Instantiate 'oic.sec.dpairing'\r
- ret = CreateDpairingResource();\r
- if (OC_STACK_OK != ret)\r
- {\r
- DeInitDpairingResource();\r
- }\r
- return ret;\r
-}\r
-\r
-/**\r
- * Perform cleanup for Dpairing resources.\r
- *\r
- * @return\r
- * OC_STACK_OK - no error\r
- * OC_STACK_ERROR - stack process error\r
- *\r
- */\r
-OCStackResult DeInitDpairingResource()\r
-{\r
- OCStackResult ret = OCDeleteResource(gDpairHandle);\r
- gDpair = NULL;\r
-\r
- if(OC_STACK_OK == ret)\r
- {\r
- return OC_STACK_OK;\r
- }\r
- else\r
- {\r
- return OC_STACK_ERROR;\r
- }\r
-}\r
-\r
-\r
-\r
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "ocstack.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "cJSON.h"
+#include "base64.h"
+#include "resourcemanager.h"
+#include "dpairingresource.h"
+#include "psinterface.h"
+#include "utlist.h"
+#include "srmresourcestrings.h"
+#include "cainterface.h"
+#include "doxmresource.h"
+#include "pconfresource.h"
+#include "credresource.h"
+#include "aclresource.h"
+#include "srmutility.h"
+#include "ocserverrequest.h"
+#include "ocpayloadcbor.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
+#include <stdlib.h>
+#ifdef WITH_ARDUINO
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#ifdef __WITH_DTLS__
+#include "global.h"
+#endif
+
+#define TAG "SRM-DPAIRING"
+
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching belox max cbor size. */
+static const uint16_t CBOR_SIZE = 1024;
+
+/** Max cbor size payload. */
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+/** DOXM Map size - Number of mandatory items. */
+static const uint8_t DPAIR_MAP_SIZE = 3;
+
+static OicSecDpairing_t *gDpair = NULL;
+static OCResourceHandle gDpairHandle = NULL;
+static OicSecDpairing_t gDefaultDpair =
+{
+ PRM_NOT_ALLOWED, /* OicSecPrm_t spm */
+ {.id = {0}}, /* OicUuid_t pdeviceID */
+ {.id = {0}}, /* OicUuid_t rowner */
+};
+
+void DeleteDpairingBinData(OicSecDpairing_t* dpair)
+{
+ if (dpair)
+ {
+ //Clean dpairing itself
+ OICFree(dpair);
+ }
+}
+
+/**
+ * Get the default value.
+ * @retval the gDefaultDpair pointer;
+ */
+static OicSecDpairing_t* GetDpairingDefault()
+{
+ OIC_LOG (DEBUG, TAG, "GetDpairingDefault");
+
+ return &gDefaultDpair;
+}
+
+/**
+ * This method is used by SRM to retrieve Dpairing resource data..
+ */
+void SetDpairingResourceOwner(OicUuid_t *rowner)
+{
+ OIC_LOG (DEBUG, TAG, "SetDpairingResourceOwner");
+ if (gDpair)
+ {
+ memcpy(&gDpair->rownerID, rowner, sizeof(OicUuid_t));
+ }
+}
+
+#ifdef __WITH_DTLS__
+/**
+ * Function to save PairingPSK.
+ *
+ * @param[in] endpoint current endpoint.
+ * @param[in] peerDevID peer device indentitiy.
+ * @param[in] isPairingServer indicate if it generates PairingPSK for server or client.
+ *
+ * @return OC_STACK_OK on success
+ */
+OCStackResult SavePairingPSK(OCDevAddr *endpoint,
+ OicUuid_t *peerDevID, OicUuid_t *owner, bool isPairingServer)
+{
+ OIC_LOG(DEBUG, TAG, "IN SavePairingPSK");
+
+ if(NULL == endpoint || NULL == peerDevID || NULL == owner)
+ {
+ OIC_LOG_V(ERROR, TAG, "Invalid Input parameters in [%s]\n", __FUNCTION__);
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCStackResult res = OC_STACK_ERROR;
+
+ OicUuid_t ptDeviceID = {.id={0}};
+ if (OC_STACK_OK != GetDoxmDeviceID(&ptDeviceID))
+ {
+ OIC_LOG(ERROR, TAG, "Error while retrieving provisioning tool's device ID");
+ return res;
+ }
+
+ uint8_t pairingPSK[OWNER_PSK_LENGTH_128] = {0};
+ OicSecKey_t pairingKey = {pairingPSK, OWNER_PSK_LENGTH_128};
+
+ //Generating PairingPSK using OwnerPSK scheme
+ CAResult_t pskRet = CAGenerateOwnerPSK((const CAEndpoint_t *)endpoint,
+ (uint8_t *)OIC_RSRC_TYPE_SEC_DPAIRING,
+ strlen(OIC_RSRC_TYPE_SEC_DPAIRING),
+ (isPairingServer ? ptDeviceID.id : peerDevID->id), sizeof(OicUuid_t), // server
+ (isPairingServer ? peerDevID->id : ptDeviceID.id), sizeof(OicUuid_t), // client
+ pairingPSK, OWNER_PSK_LENGTH_128);
+
+ if (CA_STATUS_OK == pskRet)
+ {
+ OIC_LOG(INFO, TAG, "pairingPSK dump:\n");
+ OIC_LOG_BUFFER(INFO, TAG, pairingPSK, OWNER_PSK_LENGTH_128);
+ //Generating new credential for direct-pairing client
+
+ OicSecCred_t *cred = GenerateCredential(peerDevID,
+ SYMMETRIC_PAIR_WISE_KEY, NULL,
+ &pairingKey, owner);
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+
+ res = AddCredential(cred);
+ if(res != OC_STACK_OK)
+ {
+ DeleteCredList(cred);
+ return res;
+ }
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
+ }
+
+ OIC_LOG(DEBUG, TAG, "OUT SavePairingPSK");
+exit:
+ return res;
+}
+#endif // __WITH_DTLS__
+
+OCStackResult DpairingToCBORPayload(const OicSecDpairing_t *dpair, uint8_t **payload, size_t *size)
+{
+ if (NULL == dpair || NULL == payload || NULL != *payload || NULL == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ size_t cborLen = *size;
+ if (0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
+ }
+
+ *payload = NULL;
+ *size = 0;
+
+ OCStackResult ret = OC_STACK_ERROR;
+
+ CborEncoder encoder;
+ CborEncoder dpairMap;
+
+ int64_t cborEncoderResult = CborNoError;
+ uint8_t mapSize = DPAIR_MAP_SIZE;
+
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &dpairMap, mapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating DPAIRING Map");
+
+ //spm -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_SPM_NAME,
+ strlen(OIC_JSON_SPM_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SPM name tag");
+ cborEncoderResult = cbor_encode_int(&dpairMap, dpair->spm);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SPM value");
+
+ //PDEVICEID -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_PDEVICE_ID_NAME,
+ strlen(OIC_JSON_PDEVICE_ID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PDeviceID tag");
+ {
+ char *deviceId = NULL;
+ ret = ConvertUuidToStr(&dpair->pdeviceID, &deviceId);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&dpairMap, deviceId, strlen(deviceId));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode PDeviceID value");
+ OICFree(deviceId);
+ }
+
+ //ROWNER -- Mandatory
+ {
+ char *rowner = NULL;
+ cborEncoderResult = cbor_encode_text_string(&dpairMap, OIC_JSON_ROWNERID_NAME,
+ strlen(OIC_JSON_ROWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROWNER tag");
+ ret = ConvertUuidToStr(&dpair->rownerID, &rowner);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&dpairMap, rowner, strlen(rowner));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Rowner ID value");
+ OICFree(rowner);
+ }
+
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &dpairMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close dpairMap");
+
+ if (CborNoError == cborEncoderResult)
+ {
+ *size = encoder.ptr - outPayload;
+ *payload = outPayload;
+ ret = OC_STACK_OK;
+ }
+
+exit:
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+ {
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = DpairingToCBORPayload(dpair, payload, &cborLen);
+ *size = cborLen;
+ }
+
+ if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *payload = NULL;
+ *size = 0;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
+}
+
+OCStackResult CBORPayloadToDpair(const uint8_t *cborPayload, size_t size,
+ OicSecDpairing_t **secDpair)
+{
+ if (NULL == cborPayload || NULL == secDpair || NULL != *secDpair || 0 == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCStackResult ret = OC_STACK_ERROR;
+ *secDpair = NULL;
+
+ CborValue dpairCbor = { .parser = NULL };
+ CborParser parser = { .end = NULL };
+ CborError cborFindResult = CborNoError;
+
+ cbor_parser_init(cborPayload, size, 0, &parser, &dpairCbor);
+ CborValue dpairMap = { .parser = NULL };
+ OicSecDpairing_t *dpair = NULL;
+ cborFindResult = cbor_value_enter_container(&dpairCbor, &dpairMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering DPairing Map");
+
+ dpair = (OicSecDpairing_t *)OICCalloc(1, sizeof(*dpair));
+ VERIFY_NON_NULL(TAG, dpair, ERROR);
+
+ while (cbor_value_is_valid(&dpairMap))
+ {
+ char *name = NULL;
+ size_t len = 0;
+ CborType type = CborInvalidType;
+ cborFindResult = cbor_value_dup_text_string(&dpairMap, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding tag name");
+ cborFindResult = cbor_value_advance(&dpairMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing a value in DPair map");
+
+ type = cbor_value_get_type(&dpairMap);
+ if (0 == strcmp(OIC_JSON_SPM_NAME, name))
+ {
+ cborFindResult = cbor_value_get_int(&dpairMap, (int *) &dpair->spm);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SPM Value");
+ }
+
+ if (0 == strcmp(OIC_JSON_PDEVICE_ID_NAME, name))
+ {
+ char *id = NULL;
+ cborFindResult = cbor_value_dup_text_string(&dpairMap, &id, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PDeviceID value");
+ ret = ConvertStrToUuid(id, &dpair->pdeviceID);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(id);
+ }
+
+ if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name))
+ {
+ char *id = NULL;
+ cborFindResult = cbor_value_dup_text_string(&dpairMap, &id, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RownerID value");
+ ret = ConvertStrToUuid(id, &dpair->rownerID);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(id);
+ }
+
+ if (CborMapType != type && cbor_value_is_valid(&dpairMap))
+ {
+ cborFindResult = cbor_value_advance(&dpairMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing the Dpair Map");
+ }
+ OICFree(name);
+ }
+
+ *secDpair = dpair;
+ ret = OC_STACK_OK;
+
+exit:
+ if (CborNoError != cborFindResult)
+ {
+ OIC_LOG (ERROR, TAG, "CBORPayloadToDoxm failed");
+ DeleteDpairingBinData(dpair);
+ dpair = NULL;
+ *secDpair = NULL;
+ ret = OC_STACK_ERROR;
+ }
+ return ret;
+}
+/**
+ * Function to handle the handshake result in Direct-Pairing.
+ * This function will be invoked after DTLS handshake
+ * @param endPoint [IN] The remote endpoint.
+ * @param errorInfo [IN] Error information from the endpoint.
+ * @return NONE
+ */
+void DPairingDTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
+{
+ OIC_LOG_V(INFO, TAG, "IN DPairingDTLSHandshakeCB");
+
+ if(gDpair && endpoint && info)
+ {
+ OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
+ endpoint->addr, endpoint->port, info->result);
+
+ if(CA_STATUS_OK == info->result)
+ {
+ OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Connection success.");
+ }
+ else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
+ {
+ OIC_LOG(INFO, TAG, "DPairingDTLSHandshakeCB - Authentication failed");
+
+ }
+
+#ifdef __WITH_DTLS__
+ CARegisterDTLSHandshakeCallback(NULL);
+#endif // __WITH_DTLS__
+
+ // delete temporary key
+ RemoveCredential(&gDpair->pdeviceID);
+ }
+
+ OIC_LOG_V(INFO, TAG, "OUT DPairingDTLSHandshakeCB");
+}
+
+static OCEntityHandlerResult HandleDpairingPostRequest (const OCEntityHandlerRequest * ehRequest)
+{
+ OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing POST request");
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+ OicSecDpairing_t* newDpair = NULL;
+ OCStackResult res = OC_STACK_OK;
+
+ const OicSecPconf_t *pconf = GetPconfResourceData();
+ if (true == pconf->edp)
+ {
+ uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
+ if (payload)
+ {
+ res = CBORPayloadToDpair(payload, size, &newDpair);
+ }
+ }
+ else
+ {
+ OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled");
+ ehRet = OC_EH_ERROR;
+ }
+
+ if (OC_STACK_OK == res && newDpair && false == IsPairedDevice(&newDpair->pdeviceID))
+ {
+ // Check if valid Post request
+ bool prmMached = false;
+ for (size_t i=0; i<pconf->prmLen; i++)
+ {
+ if (newDpair->spm == pconf->prm[i])
+ {
+ prmMached = true;
+ break;
+ }
+ }
+ OIC_LOG_V(DEBUG, TAG, "Parsed spm is %s", prmMached ? "valid" :
+ "invalid, send error response");
+
+ // Update local Dpairing with new Dpairing & prepare dtls session
+ if (prmMached && '\0' != (char)newDpair->pdeviceID.id[0])
+ {
+ if(!gDpair)
+ {
+ gDpair = GetDpairingDefault();
+ }
+ gDpair->spm = newDpair->spm;
+ memcpy(&gDpair->pdeviceID, &newDpair->pdeviceID, sizeof(OicUuid_t));
+ memcpy(&gDpair->rownerID, &pconf->rownerID, sizeof(OicUuid_t));
+
+#ifdef __WITH_DTLS__
+ // Add temporary psk
+ OCStackResult res;
+ OicUuid_t subjectId = {.id={0}};
+ res = AddTmpPskWithPIN(&gDpair->pdeviceID,
+ SYMMETRIC_PAIR_WISE_KEY,
+ (char*)pconf->pin.val, DP_PIN_LENGTH,
+ &gDpair->rownerID, &subjectId);
+ if(res != OC_STACK_OK ||
+ memcmp(&gDpair->pdeviceID, &subjectId, sizeof(OicUuid_t)))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to save the temporal PSK : %d", res);
+ goto exit;
+ }
+
+ // Prepare to establish a secure channel with Pin-based PSK cipher suite
+ if (CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false) ||
+ CA_STATUS_OK != CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
+ goto exit;
+ }
+
+ if(CA_STATUS_OK != CARegisterDTLSHandshakeCallback(DPairingDTLSHandshakeCB))
+ {
+ OIC_LOG(WARNING, TAG, "DirectPairingHandler : Failed to register"
+ " DTLS handshake callback.");
+ goto exit;
+ }
+#endif // __WITH_DTLS__
+
+ // should be lock /oic/sec/dpairing resource if Direct-Pairing starts normally ?
+ OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource created");
+
+ ehRet = OC_EH_RESOURCE_CREATED;
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Error in request check");
+ }
+ }
+
+
+#ifdef __WITH_DTLS__
+exit:
+#endif // __WITH_DTLS__
+
+ // Send payload to request originator
+ if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPostRequest");
+ }
+
+ if (OC_EH_ERROR == ehRet && gDpair)
+ {
+ RemoveCredential(&gDpair->pdeviceID);
+ gDpair = NULL;
+ }
+
+ DeleteDpairingBinData(newDpair);
+ OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
+ return ehRet;
+}
+
+static OCEntityHandlerResult HandleDpairingPutRequest (const OCEntityHandlerRequest * ehRequest)
+{
+ OIC_LOG (DEBUG, TAG, "Dpairing EntityHandle processing PUT request (Comfirmation)");
+
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+ OicSecDpairing_t* newDpair = NULL;
+ OCStackResult res = OC_STACK_OK;
+
+ const OicSecPconf_t *pconf = GetPconfResourceData();
+ if (true == pconf->edp)
+ {
+ uint8_t *payload = ((OCSecurityPayload*)ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload*)ehRequest->payload)->payloadSize;
+ if (payload)
+ {
+ res = CBORPayloadToDpair(payload, size, &newDpair);
+ }
+
+ }
+ else
+ {
+ OIC_LOG (DEBUG, TAG, "EDP == false : Direct-Pairing Disabled");
+ ehRet = OC_EH_ERROR;
+ }
+
+
+ if ((OC_STACK_OK == res) && gDpair && newDpair)
+ {
+ OIC_LOG(DEBUG, TAG, "Received direct-pairing finalization request");
+
+ // Check if valid Put request
+ VERIFY_SUCCESS(TAG, PRM_NOT_ALLOWED == newDpair->spm, ERROR);
+
+ const OicSecPconf_t *pconf = GetPconfResourceData();
+ VERIFY_NON_NULL(TAG, pconf, ERROR);
+
+#ifdef __WITH_DTLS__
+ OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;
+ VERIFY_SUCCESS(TAG, (request->devAddr.flags | OC_FLAG_SECURE), ERROR);
+
+ //Generate new credential
+ OIC_LOG_V(INFO, TAG, "SavePairingPSK for %s(%d)", request->devAddr.addr,
+ request->devAddr.port);
+ OCStackResult res = SavePairingPSK(&request->devAddr, &newDpair->pdeviceID,
+ (OicUuid_t *)&pconf->rownerID, true);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
+#endif //__WITH_DTLS__
+
+ //Generate new acl
+ OicSecPdAcl_t *pdAcl;
+ LL_FOREACH(pconf->pdacls, pdAcl)
+ {
+ OicSecAcl_t acl;
+ memset(&acl, 0, sizeof(OicSecAcl_t));
+ memcpy(&acl.subject, &gDpair->pdeviceID, sizeof(OicUuid_t));
+ acl.resources = pdAcl->resources;
+ acl.resourcesLen = pdAcl->resourcesLen;
+ memcpy(&acl.rownerID, &pconf->rownerID, sizeof(OicUuid_t));
+ acl.permission = pdAcl->permission;
+ acl.periods = pdAcl->periods;
+ acl.recurrences = pdAcl->recurrences;
+ acl.prdRecrLen = pdAcl->prdRecrLen;
+
+ size_t size = 0;
+ uint8_t *payload = NULL;
+ if (OC_STACK_OK == AclToCBORPayload(&acl, &payload, &size))
+ {
+ InstallNewACL(payload, size);
+ OICFree(payload);
+ }
+ }
+
+ //update pconf device list
+ AddPairedDevice(&newDpair->pdeviceID);
+
+ //Initialize dpairing resource
+ gDpair = NULL;
+
+ OIC_LOG (DEBUG, TAG, "/oic/sec/dpairing resource updated,"
+ "direct-pairing finalization success");
+ ehRet = OC_EH_OK;
+ }
+
+exit:
+
+ //Send payload to request originator
+ if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingPutRequest");
+ }
+
+ DeleteDpairingBinData(newDpair);
+ OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
+ return ehRet;
+}
+/*
+ * This internal method is the entity handler for Dpairing resources and
+ * will handle REST request (GET/POST) for them.
+ */
+OCEntityHandlerResult DpairingEntityHandler (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void* callbackParameter)
+{
+ OIC_LOG(DEBUG, TAG, "Received request DpairingEntityHandler");
+ (void)callbackParameter;
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+ if (!ehRequest)
+ {
+ return ehRet;
+ }
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
+ switch (ehRequest->method)
+ {
+ case OC_REST_GET:
+ break;
+
+ case OC_REST_POST:
+ ehRet = HandleDpairingPostRequest(ehRequest);
+ break;
+
+ case OC_REST_PUT:
+ ehRet = HandleDpairingPutRequest(ehRequest);
+ break;
+
+ case OC_REST_DELETE:
+ break;
+
+ default:
+ ehRet = OC_EH_ERROR;
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
+ }
+ }
+
+ return ehRet;
+}
+
+/*
+ * This internal method is used to create '/oic/sec/dpairing' resource.
+ */
+OCStackResult CreateDpairingResource()
+{
+ OCStackResult ret;
+
+ ret = OCCreateResource(&gDpairHandle,
+ OIC_RSRC_TYPE_SEC_DPAIRING,
+ OIC_MI_DEF,
+ OIC_RSRC_DPAIRING_URI,
+ DpairingEntityHandler,
+ NULL,
+ OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
+
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Unable to instantiate Dpairing resource");
+ DeInitDpairingResource();
+ }
+ return ret;
+}
+
+/**
+ * Initialize Dpairing resource by loading data from persistent storage.
+ *
+ * @retval OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitDpairingResource()
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ // Instantiate 'oic.sec.dpairing'
+ ret = CreateDpairingResource();
+ if (OC_STACK_OK != ret)
+ {
+ DeInitDpairingResource();
+ }
+ return ret;
+}
+
+/**
+ * Perform cleanup for Dpairing resources.
+ *
+ * @return
+ * OC_STACK_OK - no error
+ * OC_STACK_ERROR - stack process error
+ *
+ */
+OCStackResult DeInitDpairingResource()
+{
+ OCStackResult ret = OCDeleteResource(gDpairHandle);
+ gDpair = NULL;
+
+ if(OC_STACK_OK == ret)
+ {
+ return OC_STACK_OK;
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
+}
+
+OCStackResult SetDpairingRownerId(const OicUuid_t* newROwner)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ uint8_t *cborPayload = NULL;
+ size_t size = 0;
+ OicUuid_t prevId = {.id={0}};
+
+ if(NULL == newROwner)
+ {
+ ret = OC_STACK_INVALID_PARAM;
+ }
+ if(NULL == gDpair)
+ {
+ ret = OC_STACK_NO_RESOURCE;
+ }
+
+ if(newROwner && gDpair)
+ {
+ memcpy(prevId.id, gDpair->rownerID.id, sizeof(prevId.id));
+ memcpy(gDpair->rownerID.id, newROwner->id, sizeof(newROwner->id));
+
+ ret = DpairingToCBORPayload(gDpair, &cborPayload, &size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ ret = UpdateSecureResourceInPS(OIC_JSON_DPAIRING_NAME, cborPayload, size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ OICFree(cborPayload);
+ }
+
+ return ret;
+
+exit:
+ OICFree(cborPayload);
+ memcpy(gDpair->rownerID.id, prevId.id, sizeof(prevId.id));
+ return ret;
+}
+
+OCStackResult GetDpairingRownerId(OicUuid_t *rowneruuid)
+{
+ OCStackResult retVal = OC_STACK_ERROR;
+ if (gDpair)
+ {
+ *rowneruuid = gDpair->rownerID;
+ retVal = OC_STACK_OK;
+ }
+ return retVal;
+}
static const char BYDAY[] = "BYDAY";
static const char DAILY[] = "DAILY";
-
-/**
- * Parses periodStr and populate struct IotvtICalPeriod_t
- *
- * @param periodStr string to be parsed.
- * @param period IotvtICalPeriod_t struct to be populated.
- *
- * @return IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
- * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
- * IOTVTICAL_INVALID_SUCCESS -- if no error while parsing
- */
IotvtICalResult_t ParsePeriod(const char *periodStr, IotvtICalPeriod_t *period)
{
- if((NULL == periodStr) || (NULL == period))
+ if ((NULL == periodStr) || (NULL == period))
{
return IOTVTICAL_INVALID_PARAMETER;
}
//startDateTime and endDateTime must be same form
//Eg: periodStr = "20150629T153050/20150630T203055"
// periodStr = "20150629/20150630"
- if(NULL == (endDTPos = strchr(periodStr, '/')))
+ if (NULL == (endDTPos = strchr(periodStr, '/')))
{
return IOTVTICAL_INVALID_PERIOD;
}
endDTLen = strlen(endDTPos);
//Checking if both startDateTime and endDateTime are of same form
- if(startDTLen == endDTLen)
+ if (startDTLen == endDTLen)
{
- if(8 == startDTLen) //YYYYmmdd
+ if (8 == startDTLen) //YYYYmmdd
{
fmt = dFormat;
}
- else if(15 == startDTLen) //YYYYmmddTHHMMSS
+ else if (15 == startDTLen) //YYYYmmddTHHMMSS
{
fmt = dtFormat;
}
}
//Checking if startDateTime has right format
- if(NULL != strptime(periodStr, fmt, &period->startDateTime))
+ if (NULL != strptime(periodStr, fmt, &period->startDateTime))
{
//Checking if endDateTime has right format
- if(NULL != strptime(endDTPos, fmt, &period->endDateTime))
+ if (NULL != strptime(endDTPos, fmt, &period->endDateTime))
{
//Checking if endDateTime is after startDateTime
if ((period->startDateTime.tm_year > period->endDateTime.tm_year)
return IOTVTICAL_INVALID_PERIOD;
}
-
/**
- * Parses untilRule and populate "until" field of struct IotvtICalRecur_t
+ * Parses untilRule and populate "until" field of struct IotvtICalRecur_t.
*
- * @param untilRule string to be parsed.
- * @param recur IotvtICalRecur_t struct to be populated.
+ * @param untilRule is a string to be parsed.
+ * @param recur is the reference to the @ref IotvtICalRecur_t to be populated.
*
- * @return IOTVTICAL_ERRRO -- if untilRule has invalid format
- * IOTVTICAL_INVALID_SUCCESS -- if no error while parsing
+ * @return ::IOTVTICAL_SUCCESS is succesful, else in case of error
+ * ::IOTVTICAL_ERROR, if untilRule has invalid format or ::IOTVTICAL_INVALID_SUCCESS,
+ * if no error while parsing.
*/
static IotvtICalResult_t ParseDate(char *untilRule, IotvtICalRecur_t *recur)
{
char *date = strchr(untilRule, '=');
- if(NULL == date)
+ if (NULL == date)
{
return IOTVTICAL_ERROR;
}
date += 1;
- if(strlen(date) == 8) //YYYYmmdd
+ if (strlen(date) == 8) //YYYYmmdd
{
- if(NULL != strptime(date, dFormat, &recur->until))
+ if (NULL != strptime(date, dFormat, &recur->until))
{
return IOTVTICAL_SUCCESS;
}
return IOTVTICAL_ERROR;
}
-
/**
- * Parses bydayRule and populate "byDay" field of struct IotvtICalRecur_t
+ * Parses bydayRule and populate "byDay" field of struct @ref IotvtICalRecur_t.
*
- * @param bydayRule string to be parsed.
- * @param recur IotvtICalRecur_t struct to be populated.
+ * @param bydayRule is a string to be parsed.
+ * @param recur is a reference to @ref IotvtICalRecur_t struct to be populated.
*
- * @return IOTVTICAL_ERRRO -- if bydayRule has empty weekday list or invalid weekdays
- * IOTVTICAL_INVALID_SUCCESS -- if no error while parsing
+ * @return ::IOTVTICAL_SUCCESS is succesful, else in case of error ::IOTVTICAL_ERROR,
+ * if bydayRule has empty weekday list or invalid weekdays.
*/
static IotvtICalResult_t ParseByday(char *bydayRule, IotvtICalRecur_t *recur)
{
- if(strstr(bydayRule, "SU"))
+ if (strstr(bydayRule, "SU"))
{
recur->byDay = recur->byDay | SUNDAY;
}
- if(strstr(bydayRule, "MO"))
+ if (strstr(bydayRule, "MO"))
{
recur->byDay = recur->byDay | MONDAY;
}
- if(strstr(bydayRule, "TU"))
+ if (strstr(bydayRule, "TU"))
{
recur->byDay = recur->byDay | TUESDAY;
}
- if(strstr(bydayRule, "WE"))
+ if (strstr(bydayRule, "WE"))
{
recur->byDay = recur->byDay | WEDNESDAY;
}
- if(strstr(bydayRule, "TH"))
+ if (strstr(bydayRule, "TH"))
{
recur->byDay = recur->byDay | THURSDAY;
}
- if(strstr(bydayRule, "FR"))
+ if (strstr(bydayRule, "FR"))
{
recur->byDay = recur->byDay | FRIDAY;
}
- if(strstr(bydayRule, "SA"))
+ if (strstr(bydayRule, "SA"))
{
recur->byDay = recur->byDay | SATURDAY;
}
//Checking if byDay list is empty or has inValid weekdays
- if(recur->byDay == NO_WEEKDAY)
+ if (recur->byDay == NO_WEEKDAY)
{
return IOTVTICAL_ERROR;
}
return IOTVTICAL_SUCCESS;
}
-
-/**
- * Parses recurStr and populate struct IotvtICalRecur_t
- *
- * @param recurStr string to be parsed.
- * @param recur IotvtICalPeriod_t struct to be populated.
- *
- * @return IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
- * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
- * IOTVTICAL_INVALID_RRULE -- if rrule string has invalid format
- */
IotvtICalResult_t ParseRecur(const char *recurStr, IotvtICalRecur_t *recur)
{
-
- if((NULL == recurStr) || (NULL == recur))
+ if ((NULL == recurStr) || (NULL == recur))
{
return IOTVTICAL_INVALID_PARAMETER;
}
startPos = recurStr;
//Iterates though recurrence rule
//Eg, RRULE: FREQ=DAILY; UNTIL=20150703; BYDAY=MO, WE, FR
- while('\0' != startPos)
+ while ('\0' != startPos)
{
endPos = strchr(startPos, ';');
- if(endPos)
+ if (endPos)
{
endPos += 1;
}
OICStrcpy(buf, (endPos - startPos), startPos);
- if(NULL != strstr(buf, FREQ))
+ if (NULL != strstr(buf, FREQ))
{
- if(NULL != strstr(buf, DAILY))
+ if (NULL != strstr(buf, DAILY))
{
recur->freq = FREQ_DAILY;
freqFlag = 1;
return IOTVTICAL_INVALID_RRULE;
}
}
- else if(NULL != strstr(buf, UNTIL))
+ else if (NULL != strstr(buf, UNTIL))
{
- if(IOTVTICAL_SUCCESS != ParseDate(buf, recur))
+ if (IOTVTICAL_SUCCESS != ParseDate(buf, recur))
{
return IOTVTICAL_INVALID_RRULE;
}
}
- else if(NULL != strstr(buf, BYDAY))
+ else if (NULL != strstr(buf, BYDAY))
{
- if(IOTVTICAL_SUCCESS != ParseByday(buf, recur))
+ if (IOTVTICAL_SUCCESS != ParseByday(buf, recur))
{
return IOTVTICAL_INVALID_RRULE;
};
startPos = endPos;
}
- if(1 != freqFlag)
+ if (1 != freqFlag)
{
return IOTVTICAL_INVALID_RRULE;
}
int days;
int leapDays=0;
- if(date2->tm_year > date1->tm_year)
+ if (date2->tm_year > date1->tm_year)
{
- for(int y = date1->tm_year; y < date2->tm_year; y++)
+ for (int y = date1->tm_year; y < date2->tm_year; y++)
{
y += TM_YEAR_OFFSET;
- if(y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
+ if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
{
leapDays += 1;
}
return days;
}
-
/**
* Computes number of seconds between two time.
*
}
/**
- * Validates if the @param currentTime is with in allowable period
+ * Validates if the @param currentTime is with in allowable period.
*
- * @param period -- allowable period
- * @param currentTime -- the time that need to be validated against allowable time
+ * @param period allowable period.
+ * @param currentTime the time that need to be validated against allowable time.
*
- * @return IOTVTICAL_VALID_ACCESS -- if the request is within valid time period
- * IOTVTICAL_INVALID_ACCESS -- if the request is not within valid time period
- * IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
+ * @return ::IOTVTICAL_VALID_ACCESS, if the request is within valid time period.
+ * ::IOTVTICAL_INVALID_ACCESS, if the request is not within valid time period.
+ * ::IOTVTICAL_INVALID_PARAMETER, if parameter are invalid.
*/
static IotvtICalResult_t ValidatePeriod(IotvtICalPeriod_t *period, IotvtICalDateTime_t *currentTime)
{
- if(NULL == period || NULL == currentTime)
+ if (NULL == period || NULL == currentTime)
{
return IOTVTICAL_INVALID_PARAMETER;
}
//If today is the start day of the allowable period then check
//currentTime > allowable period startTime
- if(todayIsStartDay)
+ if (todayIsStartDay)
{
validStartTime = (0 <= DiffSecs(&period->startDateTime, currentTime)) ? true : false;
}
//If today is the end day of allowable period then check
//currentTime < allowable period endTime
- if(todayIsEndDay)
+ if (todayIsEndDay)
{
validEndTime = (0 <= DiffSecs(currentTime, &period->endDateTime)) ? true :false;
}
//Check if today is valid day between startDate and EndDate inclusive
- if((0 <= DiffDays(&period->startDateTime, currentTime)) &&
+ if ((0 <= DiffDays(&period->startDateTime, currentTime)) &&
(0 <= DiffDays(currentTime, &period->endDateTime)))
{
validDay = true;
}
- if(validDay && validStartTime && validEndTime)
+ if (validDay && validStartTime && validEndTime)
{
return IOTVTICAL_VALID_ACCESS;
}
}
}
-/**
- * This API is used by policy engine to checks if the
- * request to access resource is within valid time.
- *
- * @param period string representing period.
- * @param recur string representing recurrence rule
- *
- * @return IOTVTICAL_VALID_ACCESS -- if the request is within valid time period
- * IOTVTICAL_INVALID_ACCESS -- if the request is not within valid time period
- * IOTVTICAL_INVALID_PARAMETER -- if parameter are invalid
- * IOTVTICAL_INVALID_PERIOD -- if period string has invalid format
- * IOTVTICAL_INVALID_RRULE -- if rrule string has invalid format
- */
-
-IotvtICalResult_t IsRequestWithinValidTime(char *periodStr, char *recurStr)
+IotvtICalResult_t IsRequestWithinValidTime(const char *periodStr, const char *recurStr)
{
//NULL recur rule means no recurring patter exist.
//Period can't be null. Period is used with or without
//recur rule to compute allowable access time.
- if(NULL == periodStr)
+ if (NULL == periodStr)
{
return IOTVTICAL_INVALID_PARAMETER;
}
IotvtICalDateTime_t *currentTime = localtime(&rawTime);
ret = ParsePeriod(periodStr, &period);
- if(ret != IOTVTICAL_SUCCESS)
+ if (ret != IOTVTICAL_SUCCESS)
{
return ret;
}
//If recur is NULL then the access time is between period's startDateTime and endDateTime
- if(NULL == recurStr)
+ if (NULL == recurStr)
{
ret = ValidatePeriod(&period, currentTime);
}
//is computed from period's startDate and the last instance is computed from
//"UNTIL". If "UNTIL" is not specified then the recurrence goes for forever.
//Eg, RRULE: FREQ=DAILY; UNTIL=20150703; BYDAY=MO, WE, FR
- if(NULL != recurStr)
+ if (NULL != recurStr)
{
ret = ParseRecur(recurStr, &recur);
- if(ret != IOTVTICAL_SUCCESS)
+ if (ret != IOTVTICAL_SUCCESS)
{
return ret;
}
- if((0 <= DiffSecs(&period.startDateTime, currentTime))&&
+ if ((0 <= DiffSecs(&period.startDateTime, currentTime))&&
(0 <= DiffSecs(currentTime, &period.endDateTime)) &&
(0 <= DiffDays(&period.startDateTime, currentTime)))
{
ret = IOTVTICAL_VALID_ACCESS;
//"UNTIL" is an optional parameter of RRULE, checking if until present in recur
- if(0 != memcmp(&recur.until, &emptyDT, sizeof(IotvtICalDateTime_t)))
+ if (0 != memcmp(&recur.until, &emptyDT, sizeof(IotvtICalDateTime_t)))
{
if(0 > DiffDays(currentTime, &recur.until))
{
}
//"BYDAY" is an optional parameter of RRULE, checking if byday present in recur
- if(NO_WEEKDAY != recur.byDay)
+ if (NO_WEEKDAY != recur.byDay)
{
int isValidWD = (0x1 << currentTime->tm_wday) & recur.byDay; //Valid weekdays
- if(!isValidWD)
+ if (!isValidWD)
{
ret = IOTVTICAL_INVALID_ACCESS;
}
-/* *****************************************************************
- *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * *****************************************************************/
-
- #include <memory.h>
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <memory.h>
#include "ocstack.h"
#include "ocrandom.h"
return ret;
}
#endif //__WITH_DTLS__
-
-/* *****************************************************************
- *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * *****************************************************************/
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
#include <string.h>
#include <math.h>
#include "pbkdf2.h"
#define TAG "PBDKF2"
#define XOR_BUF(in, out, bufSize)\
-do{\
+do \
+{\
size_t i=0;\
- for(i=0; i< (bufSize); i++)\
+ for (i=0; i< (bufSize); i++)\
{\
(out)[i] = (in)[i] ^ (out)[i];\
}\
-}while(0)\
-
+} while(0)\
static int isLittle()
{
-/* *****************************************************************\r
- *\r
- * Copyright 2016 Samsung Electronics All Rights Reserved.\r
- *\r
- *\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * *****************************************************************/\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include "ocstack.h"\r
-#include "logger.h"\r
-#include "oic_malloc.h"\r
-#include "oic_string.h"\r
-#include "cJSON.h"\r
-#include "base64.h"\r
-#include "resourcemanager.h"\r
-#include "pconfresource.h"\r
-#include "psinterface.h"\r
-#include "utlist.h"\r
-#include "srmresourcestrings.h"\r
-#include "doxmresource.h"\r
-#include "srmutility.h"\r
-#include "ocserverrequest.h"\r
-#include <stdlib.h>\r
-#ifdef WITH_ARDUINO\r
-#include <string.h>\r
-#else\r
-#include <strings.h>\r
-#endif\r
-\r
-#define TAG "SRM-PCONF"\r
-\r
-\r
-static OicSecPconf_t *gPconf = NULL;\r
-static OCResourceHandle gPconfHandle = NULL;\r
-static OicSecPconf_t gDefaultPconf =\r
-{\r
- false, /* bool edp */\r
- NULL, /* OicSecPrm *prm */\r
- 0, /* size_t prmLen */\r
- {.val = {0}}, /* OicDpPin_t pin */\r
- NULL, /* OicSecPdAcl_t *pdacls */\r
- NULL, /* OicUuid_t *pddevs */\r
- 0, /* size_t pddevLen */\r
- {.id = {0}}, /* OicUuid_t deviceID */\r
- {.id = {0}}, /* OicUuid_t rowner */\r
-};\r
-\r
-/**\r
- * This function frees OicSecPdAcl_t object's fields and object itself.\r
- */\r
-void FreePdAclList(OicSecPdAcl_t* pdacls)\r
-{\r
- if (pdacls)\r
- {\r
- size_t i = 0;\r
-\r
- //Clean pdacl objecs\r
- OicSecPdAcl_t *aclTmp1 = NULL;\r
- OicSecPdAcl_t *aclTmp2 = NULL;\r
- LL_FOREACH_SAFE(pdacls, aclTmp1, aclTmp2)\r
- {\r
- LL_DELETE(pdacls, aclTmp1);\r
-\r
- // Clean Resources\r
- for (i = 0; i < aclTmp1->resourcesLen; i++)\r
- {\r
- OICFree(aclTmp1->resources[i]);\r
- }\r
- OICFree(aclTmp1->resources);\r
-\r
- //Clean Period\r
- if(aclTmp1->periods)\r
- {\r
- for(i = 0; i < aclTmp1->prdRecrLen; i++)\r
- {\r
- OICFree(aclTmp1->periods[i]);\r
- }\r
- OICFree(aclTmp1->periods);\r
- }\r
-\r
- //Clean Recurrence\r
- if(aclTmp1->recurrences)\r
- {\r
- for(i = 0; i < aclTmp1->prdRecrLen; i++)\r
- {\r
- OICFree(aclTmp1->recurrences[i]);\r
- }\r
- OICFree(aclTmp1->recurrences);\r
- }\r
- }\r
-\r
- //Clean pconf itself\r
- OICFree(pdacls);\r
- }\r
-}\r
-\r
-void DeletePconfBinData(OicSecPconf_t* pconf)\r
-{\r
- if (pconf)\r
- {\r
- //Clean prm\r
- OICFree(pconf->prm);\r
-\r
- //Clean pdacl\r
- if (pconf->pdacls)\r
- {\r
- FreePdAclList(pconf->pdacls);\r
- }\r
-\r
- //Clean pddev\r
- OICFree(pconf->pddevs);\r
-\r
- //Clean pconf itself\r
- OICFree(pconf);\r
- }\r
-}\r
-\r
-/*\r
- * This internal method converts PCONF data into JSON format.\r
- *\r
- * Note: Caller needs to invoke 'free' when finished done using\r
- * return string.\r
- */\r
-char * BinToPconfJSON(const OicSecPconf_t * pconf)\r
-{\r
- OIC_LOG(DEBUG, TAG, "BinToPconfJSON() IN");\r
-\r
- if (NULL == pconf)\r
- {\r
- return NULL;\r
- }\r
-\r
- char *jsonStr = NULL;\r
- cJSON *jsonPconf = NULL;\r
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};\r
- uint32_t outLen = 0;\r
- B64Result b64Ret = B64_OK;\r
-\r
- cJSON *jsonRoot = cJSON_CreateObject();\r
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);\r
-\r
- jsonPconf = cJSON_CreateObject();\r
- VERIFY_NON_NULL(TAG, jsonPconf, ERROR);\r
- cJSON_AddItemToObject(jsonRoot, OIC_JSON_PCONF_NAME, jsonPconf );\r
-\r
-\r
- //EDP -- Mandatory\r
- cJSON_AddBoolToObject(jsonPconf, OIC_JSON_EDP_NAME, pconf->edp);\r
-\r
- //PRM type -- Mandatory\r
- if(0< pconf->prmLen)\r
- {\r
- cJSON *jsonPrmArray = cJSON_CreateArray();\r
- VERIFY_NON_NULL(TAG, jsonPrmArray, ERROR);\r
- cJSON_AddItemToObject (jsonPconf, OIC_JSON_PRM_NAME, jsonPrmArray);\r
- OIC_LOG_V (DEBUG, TAG, "pconf->prmLen = %d", (int)pconf->prmLen);\r
- for (size_t i = 0; i < pconf->prmLen; i++)\r
- {\r
- OIC_LOG_V (DEBUG, TAG, "pconf->prm[%d] = %d", (int)i, pconf->prm[i]);\r
- cJSON_AddItemToArray (jsonPrmArray, cJSON_CreateNumber(pconf->prm[i]));\r
- }\r
- }\r
-\r
- //PIN -- Mandatory\r
- if(DP_PIN_LENGTH == strlen((const char*)pconf->pin.val))\r
- {\r
- cJSON_AddStringToObject(jsonPconf, OIC_JSON_PIN_NAME, (char*)pconf->pin.val);\r
- }\r
-\r
- //PDACL -- Mandatory\r
- if(pconf->pdacls)\r
- {\r
- cJSON *jsonAclArray = NULL;\r
- OicSecPdAcl_t *pdacl = NULL;\r
- cJSON_AddItemToObject (jsonPconf, OIC_JSON_PDACL_NAME,\r
- jsonAclArray = cJSON_CreateArray());\r
- VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);\r
-\r
- pdacl = pconf->pdacls;\r
- while(pdacl)\r
- {\r
- cJSON *jsonAcl = cJSON_CreateObject();\r
-\r
- // Resources -- Mandatory\r
- cJSON *jsonRsrcArray = NULL;\r
- cJSON_AddItemToObject (jsonAcl, OIC_JSON_RESOURCES_NAME,\r
- jsonRsrcArray = cJSON_CreateArray());\r
- VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);\r
- for (size_t i = 0; i < pdacl->resourcesLen; i++)\r
- {\r
- cJSON_AddItemToArray (jsonRsrcArray,\r
- cJSON_CreateString(pdacl->resources[i]));\r
- }\r
-\r
- // Permissions -- Mandatory\r
- cJSON_AddNumberToObject (jsonAcl, OIC_JSON_PERMISSION_NAME, pdacl->permission);\r
-\r
- //Period & Recurrence -- Not Mandatory\r
- if(0 != pdacl->prdRecrLen && pdacl->periods)\r
- {\r
- cJSON *jsonPeriodArray = NULL;\r
- cJSON_AddItemToObject (jsonAcl, OIC_JSON_PERIODS_NAME,\r
- jsonPeriodArray = cJSON_CreateArray());\r
- VERIFY_NON_NULL(TAG, jsonPeriodArray, ERROR);\r
- for (size_t i = 0; i < pdacl->prdRecrLen; i++)\r
- {\r
- cJSON_AddItemToArray (jsonPeriodArray,\r
- cJSON_CreateString(pdacl->periods[i]));\r
- }\r
- }\r
-\r
- //Recurrence -- Not Mandatory\r
- if(0 != pdacl->prdRecrLen && pdacl->recurrences)\r
- {\r
- cJSON *jsonRecurArray = NULL;\r
- cJSON_AddItemToObject (jsonAcl, OIC_JSON_RECURRENCES_NAME,\r
- jsonRecurArray = cJSON_CreateArray());\r
- VERIFY_NON_NULL(TAG, jsonRecurArray, ERROR);\r
- for (size_t i = 0; i < pdacl->prdRecrLen; i++)\r
- {\r
- cJSON_AddItemToArray (jsonRecurArray,\r
- cJSON_CreateString(pdacl->recurrences[i]));\r
- }\r
- }\r
-\r
- // Attach current acl node to Acl Array\r
- cJSON_AddItemToArray(jsonAclArray, jsonAcl);\r
- pdacl = pdacl->next;\r
- }\r
- }\r
-\r
- //PDDev -- Mandatory\r
- //There may not be paired devices if it did not pairing before\r
- if (pconf->pddevs && 0 < pconf->pddevLen)\r
- {\r
- cJSON *jsonPdDevArray = cJSON_CreateArray();\r
- VERIFY_NON_NULL(TAG, jsonPdDevArray, ERROR);\r
- cJSON_AddItemToObject (jsonPconf, OIC_JSON_PDDEV_LIST_NAME, jsonPdDevArray );\r
- for (size_t i = 0; i < pconf->pddevLen; i++)\r
- {\r
- outLen = 0;\r
- b64Ret = b64Encode(pconf->pddevs[i].id, sizeof(pconf->pddevs[i].id), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);\r
- cJSON_AddItemToArray (jsonPdDevArray, cJSON_CreateString(base64Buff));\r
- }\r
- }\r
-\r
- //DeviceId -- Mandatory\r
- //There may not be devicd id if caller is provisoning tool\r
- if ('\0' != (char)pconf->deviceID.id[0])\r
- {\r
- outLen = 0;\r
- b64Ret = b64Encode(pconf->deviceID.id, sizeof(pconf->deviceID.id), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);\r
- cJSON_AddStringToObject(jsonPconf, OIC_JSON_DEVICE_ID_NAME, base64Buff);\r
- }\r
-\r
- //ROwner -- Mandatory\r
- VERIFY_SUCCESS(TAG, '\0' != (char)pconf->rowner.id[0], ERROR);\r
- outLen = 0;\r
- b64Ret = b64Encode(pconf->rowner.id, sizeof(pconf->rowner.id), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);\r
- cJSON_AddStringToObject(jsonPconf, OIC_JSON_ROWNER_NAME, base64Buff);\r
-\r
-\r
- jsonStr = cJSON_PrintUnformatted(jsonRoot);\r
-\r
-exit:\r
- if (jsonRoot)\r
- {\r
- cJSON_Delete(jsonRoot);\r
- }\r
- return jsonStr;\r
-}\r
-\r
-/*\r
- * This internal method converts JSON PCONF into binary PCONF.\r
- */\r
-OicSecPconf_t * JSONToPconfBin(const char * jsonStr)\r
-{\r
- OIC_LOG(DEBUG, TAG, "JSONToPconfBin() IN");\r
-\r
- OCStackResult ret = OC_STACK_ERROR;\r
- OicSecPconf_t * pconf = NULL;\r
- cJSON *jsonRoot = NULL;\r
- cJSON *jsonPconf = NULL;\r
- cJSON *jsonObj = NULL;\r
- size_t jsonObjLen = 0;\r
-\r
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};\r
- uint32_t outLen = 0;\r
- B64Result b64Ret = B64_OK;\r
-\r
-\r
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);\r
-\r
- jsonRoot = cJSON_Parse(jsonStr);\r
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);\r
-\r
- jsonPconf = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PCONF_NAME);\r
- VERIFY_NON_NULL(TAG, jsonPconf, ERROR);\r
-\r
- pconf = (OicSecPconf_t*)OICCalloc(1, sizeof(OicSecPconf_t));\r
- VERIFY_NON_NULL(TAG, pconf, ERROR);\r
-\r
- //EDP -- Mandatory\r
- jsonObj = cJSON_GetObjectItem(jsonPconf, OIC_JSON_EDP_NAME);\r
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);\r
- VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type) , ERROR);\r
- pconf->edp = jsonObj->valueint;\r
-\r
- //PRM type -- Mandatory\r
- jsonObj = cJSON_GetObjectItem(jsonPconf, OIC_JSON_PRM_NAME);\r
- if (jsonObj && cJSON_Array == jsonObj->type)\r
- {\r
- int arrLen = cJSON_GetArraySize(jsonObj);\r
- if(0 < arrLen)\r
- {\r
- pconf->prmLen = (size_t)arrLen;\r
- pconf->prm = (OicSecPrm_t *)OICCalloc(pconf->prmLen, sizeof(OicSecPrm_t));\r
- VERIFY_NON_NULL(TAG, pconf->prm, ERROR);\r
-\r
- for (size_t i = 0; i < pconf->prmLen ; i++)\r
- {\r
- cJSON *jsonPrm = cJSON_GetArrayItem(jsonObj, i);\r
- VERIFY_NON_NULL(TAG, jsonPrm, ERROR);\r
- pconf->prm[i] = (OicSecPrm_t)jsonPrm->valueint;\r
- OIC_LOG_V (DEBUG, TAG, "jsonPrm->valueint = %d", jsonPrm->valueint);\r
- OIC_LOG_V (DEBUG, TAG, "pconf->prm[%d] = %d", (int)i, pconf->prm[i]);\r
- }\r
- }\r
- }\r
-\r
- //PIN -- Mandatory\r
- jsonObj = cJSON_GetObjectItem(jsonPconf, OIC_JSON_PIN_NAME);\r
- if (jsonObj)\r
- {\r
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);\r
- VERIFY_SUCCESS(TAG, DP_PIN_LENGTH == strlen(jsonObj->valuestring), ERROR);\r
- OICStrcpy((char*)pconf->pin.val, DP_PIN_LENGTH + 1, (char*)jsonObj->valuestring);\r
- }\r
- else\r
- {\r
- memset(pconf->pin.val, 0, DP_PIN_LENGTH+1);\r
- }\r
-\r
- //PDACL -- Mandatory\r
- jsonObj = cJSON_GetObjectItem(jsonPconf, OIC_JSON_PDACL_NAME);\r
- if (jsonObj)\r
- {\r
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);\r
-\r
- OicSecPdAcl_t * headAcl = NULL;\r
- OicSecPdAcl_t * prevAcl = NULL;\r
- int numPdAcl = cJSON_GetArraySize(jsonObj);\r
- int idx = 0;\r
-\r
- while(idx < numPdAcl)\r
- {\r
- cJSON *jsonPdAcl = cJSON_GetArrayItem(jsonObj, idx);\r
- VERIFY_NON_NULL(TAG, jsonPdAcl, ERROR);\r
-\r
- OicSecPdAcl_t *pdacl = (OicSecPdAcl_t*)OICCalloc(1, sizeof(OicSecPdAcl_t));\r
- VERIFY_NON_NULL(TAG, pdacl, ERROR);\r
-\r
- headAcl = (headAcl) ? headAcl : pdacl;\r
- if (prevAcl)\r
- {\r
- prevAcl->next = pdacl;\r
- }\r
-\r
- cJSON *jsonAclObj = NULL;\r
-\r
- // Resources -- Mandatory\r
- jsonAclObj = cJSON_GetObjectItem(jsonPdAcl, OIC_JSON_RESOURCES_NAME);\r
- VERIFY_NON_NULL(TAG, jsonAclObj, ERROR);\r
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonAclObj->type, ERROR);\r
-\r
- pdacl->resourcesLen = (size_t)cJSON_GetArraySize(jsonAclObj);\r
- VERIFY_SUCCESS(TAG, pdacl->resourcesLen > 0, ERROR);\r
- pdacl->resources = (char**)OICCalloc(pdacl->resourcesLen, sizeof(char*));\r
- VERIFY_NON_NULL(TAG, (pdacl->resources), ERROR);\r
-\r
- size_t idxx = 0;\r
- do\r
- {\r
- cJSON *jsonRsrc = cJSON_GetArrayItem(jsonAclObj, idxx);\r
- VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);\r
-\r
- jsonObjLen = strlen(jsonRsrc->valuestring) + 1;\r
- pdacl->resources[idxx] = (char*)OICMalloc(jsonObjLen);\r
- VERIFY_NON_NULL(TAG, (pdacl->resources[idxx]), ERROR);\r
- OICStrcpy(pdacl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);\r
- } while ( ++idxx < pdacl->resourcesLen);\r
-\r
- // Permissions -- Mandatory\r
- jsonAclObj = cJSON_GetObjectItem(jsonPdAcl,\r
- OIC_JSON_PERMISSION_NAME);\r
- VERIFY_NON_NULL(TAG, jsonAclObj, ERROR);\r
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonAclObj->type, ERROR);\r
- pdacl->permission = jsonAclObj->valueint;\r
-\r
- //Period -- Not Mandatory\r
- cJSON *jsonPeriodObj = cJSON_GetObjectItem(jsonPdAcl,\r
- OIC_JSON_PERIODS_NAME);\r
- if(jsonPeriodObj)\r
- {\r
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonPeriodObj->type,\r
- ERROR);\r
- pdacl->prdRecrLen = (size_t)cJSON_GetArraySize(jsonPeriodObj);\r
- if(pdacl->prdRecrLen > 0)\r
- {\r
- pdacl->periods = (char**)OICCalloc(pdacl->prdRecrLen,\r
- sizeof(char*));\r
- VERIFY_NON_NULL(TAG, pdacl->periods, ERROR);\r
-\r
- cJSON *jsonPeriod = NULL;\r
- for(size_t i = 0; i < pdacl->prdRecrLen; i++)\r
- {\r
- jsonPeriod = cJSON_GetArrayItem(jsonPeriodObj, i);\r
- VERIFY_NON_NULL(TAG, jsonPeriod, ERROR);\r
-\r
- jsonObjLen = strlen(jsonPeriod->valuestring) + 1;\r
- pdacl->periods[i] = (char*)OICMalloc(jsonObjLen);\r
- VERIFY_NON_NULL(TAG, pdacl->periods[i], ERROR);\r
- OICStrcpy(pdacl->periods[i], jsonObjLen,\r
- jsonPeriod->valuestring);\r
- }\r
- }\r
- }\r
-\r
- //Recurrence -- Not mandatory\r
- cJSON *jsonRecurObj = cJSON_GetObjectItem(jsonPdAcl,\r
- OIC_JSON_RECURRENCES_NAME);\r
- if(jsonRecurObj)\r
- {\r
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonRecurObj->type,\r
- ERROR);\r
-\r
- if(pdacl->prdRecrLen > 0)\r
- {\r
- pdacl->recurrences = (char**)OICCalloc(pdacl->prdRecrLen,\r
- sizeof(char*));\r
- VERIFY_NON_NULL(TAG, pdacl->recurrences, ERROR);\r
-\r
- cJSON *jsonRecur = NULL;\r
- for(size_t i = 0; i < pdacl->prdRecrLen; i++)\r
- {\r
- jsonRecur = cJSON_GetArrayItem(jsonRecurObj, i);\r
- VERIFY_NON_NULL(TAG, jsonRecur, ERROR);\r
- jsonObjLen = strlen(jsonRecur->valuestring) + 1;\r
- pdacl->recurrences[i] = (char*)OICMalloc(jsonObjLen);\r
- VERIFY_NON_NULL(TAG, pdacl->recurrences[i], ERROR);\r
- OICStrcpy(pdacl->recurrences[i], jsonObjLen,\r
- jsonRecur->valuestring);\r
- }\r
- }\r
- }\r
-\r
- prevAcl = pdacl;\r
- idx++;\r
- }\r
-\r
- pconf->pdacls = headAcl;\r
- }\r
- else\r
- {\r
- pconf->pdacls = NULL;\r
- }\r
-\r
- //PDDev -- Mandatory\r
- jsonObj = cJSON_GetObjectItem(jsonPconf, OIC_JSON_PDDEV_LIST_NAME);\r
- if (jsonObj && cJSON_Array == jsonObj->type)\r
- {\r
- pconf->pddevLen = (size_t)cJSON_GetArraySize(jsonObj);\r
- if(0 < pconf->pddevLen)\r
- {\r
- pconf->pddevs = (OicUuid_t *)OICCalloc(pconf->pddevLen, sizeof(OicUuid_t));\r
- VERIFY_NON_NULL(TAG, pconf->pddevs, ERROR);\r
-\r
- for (size_t i = 0; i < pconf->pddevLen ; i++)\r
- {\r
- cJSON *jsonPdDev = cJSON_GetArrayItem(jsonObj, i);\r
- VERIFY_NON_NULL(TAG, jsonPdDev, ERROR);\r
-\r
- outLen = 0;\r
- b64Ret = b64Decode(jsonPdDev->valuestring, strlen(jsonPdDev->valuestring), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(pconf->pddevs[i].id)), ERROR);\r
- memcpy(pconf->pddevs[i].id, base64Buff, outLen);\r
- }\r
- }\r
- }\r
- else\r
- {\r
- pconf->pddevs = NULL;\r
- pconf->pddevLen = 0;\r
- }\r
-\r
- //DeviceId -- Mandatory\r
- outLen = 0;\r
- jsonObj = cJSON_GetObjectItem(jsonPconf, OIC_JSON_DEVICE_ID_NAME);\r
- if (jsonObj && cJSON_String == jsonObj->type)\r
- {\r
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(pconf->deviceID.id)), ERROR);\r
- memcpy(pconf->deviceID.id, base64Buff, outLen);\r
- }\r
- else\r
- {\r
- OicUuid_t deviceId = {.id = {0}};\r
- OCStackResult ret = GetDoxmDeviceID( &deviceId);\r
- VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);\r
- memcpy(&pconf->deviceID, &deviceId, sizeof(OicUuid_t));\r
- }\r
-\r
- // ROwner -- Mandatory\r
- outLen = 0;\r
- jsonObj = cJSON_GetObjectItem(jsonPconf, OIC_JSON_ROWNER_NAME);\r
- if (jsonObj && cJSON_String == jsonObj->type)\r
- {\r
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,\r
- sizeof(base64Buff), &outLen);\r
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(pconf->rowner.id)), ERROR);\r
- memcpy(pconf->rowner.id, base64Buff, outLen);\r
- }\r
- else\r
- {\r
- memset(&pconf->rowner, 0, sizeof(OicUuid_t));\r
- }\r
-\r
- ret = OC_STACK_OK;\r
-\r
-exit:\r
- cJSON_Delete(jsonRoot);\r
- if (OC_STACK_OK != ret)\r
- {\r
- DeletePconfBinData(pconf);\r
- pconf = NULL;\r
- }\r
-\r
- OIC_LOG(DEBUG, TAG, "JSONToPconfBin() OUT");\r
- return pconf;\r
-}\r
-\r
-static bool UpdatePersistentStorage(const OicSecPconf_t * pconf)\r
-{\r
- bool ret = false;\r
-\r
- // Convert PCONF data into JSON for update to persistent storage\r
- char *jsonStr = BinToPconfJSON(pconf);\r
- if (jsonStr)\r
- {\r
- cJSON *jsonPconf = cJSON_Parse(jsonStr);\r
- OICFree(jsonStr);\r
-\r
- if ((jsonPconf) &&\r
- (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PCONF_NAME, jsonPconf)))\r
- {\r
- ret = true;\r
- }\r
- cJSON_Delete(jsonPconf);\r
- }\r
- return ret;\r
-}\r
-\r
-static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest * ehRequest)\r
-{\r
- char* jsonStr = NULL;\r
- OCEntityHandlerResult ehRet = OC_EH_OK;\r
-\r
- OicSecPconf_t pconf;\r
- memset(&pconf, 0, sizeof(OicSecPconf_t));\r
-\r
- OIC_LOG (DEBUG, TAG, "Pconf EntityHandle processing GET request");\r
-\r
- if (true == GetDoxmResourceData()->dpc)\r
- {\r
- //Making response elements for Get request\r
- if( (true == gPconf->edp) && (gPconf->prm && 0 < gPconf->prmLen) &&\r
- (0 < strlen((const char*)gPconf->deviceID.id)) && (0 < strlen((const char*)gPconf->rowner.id)))\r
- {\r
- pconf.edp = true;\r
- pconf.prm = gPconf->prm;\r
- pconf.prmLen = gPconf->prmLen;\r
- memcpy(&pconf.deviceID, &gPconf->deviceID, sizeof(OicUuid_t));\r
- memcpy(&pconf.rowner, &gPconf->rowner, sizeof(OicUuid_t));\r
- OIC_LOG (DEBUG, TAG, "PCONF - direct pairing enabled");\r
- }\r
- else if (false == gPconf->edp)\r
- {\r
- pconf.edp = false;\r
- memcpy(&pconf.rowner, &gPconf->rowner, sizeof(OicUuid_t));\r
- OIC_LOG (DEBUG, TAG, "PCONF - direct pairing disable");\r
- }\r
- else\r
- {\r
- ehRet= OC_EH_ERROR;\r
- OIC_LOG (DEBUG, TAG, "PCONF - error");\r
- }\r
- }\r
- else\r
- {\r
- OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");\r
- ehRet = OC_EH_ERROR;\r
- }\r
-\r
- jsonStr = (ehRet == OC_EH_OK) ? BinToPconfJSON(&pconf) : NULL;\r
-\r
- // Send response payload to request originator\r
- if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, jsonStr))\r
- {\r
- OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDpairingGetRequest");\r
- }\r
-\r
- OICFree(jsonStr);\r
-\r
- return ehRet;\r
-}\r
-\r
-static OCEntityHandlerResult HandlePconfPostRequest (const OCEntityHandlerRequest * ehRequest)\r
-{\r
- OCEntityHandlerResult ehRet = OC_EH_OK;\r
- OicSecPconf_t* newPconf = NULL;\r
-\r
- if (true == GetDoxmResourceData()->dpc)\r
- {\r
- // Convert JSON PCONF data into binary. This will also validate the PCONF data received.\r
- newPconf = JSONToPconfBin(((OCSecurityPayload*)ehRequest->payload)->securityData);\r
- }\r
- else\r
- {\r
- OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");\r
- ehRet = OC_EH_ERROR;\r
- }\r
-\r
- if (newPconf)\r
- {\r
- // Check if valid Post request\r
- if ((true == newPconf->edp) && (0 < newPconf->prmLen) &&\r
- DP_PIN_LENGTH == strlen((const char*)newPconf->pin.val))\r
- {\r
- OicSecPrm_t *oldPrm = gPconf->prm;\r
- OicSecPdAcl_t *oldPdacl = gPconf->pdacls;\r
-\r
- // Update local PCONF with new PCONF\r
- gPconf->edp = true;\r
- memcpy(&gPconf->pin, &newPconf->pin, sizeof(OicDpPin_t));\r
- gPconf->prm = newPconf->prm;\r
- gPconf->prmLen = newPconf->prmLen;\r
- gPconf->pdacls = newPconf->pdacls;\r
- memcpy(&gPconf->rowner, &newPconf->rowner, sizeof(OicUuid_t));\r
-\r
- // to delete old value(prm, pdacl)\r
- newPconf->prm = oldPrm;\r
- newPconf->pdacls = oldPdacl;\r
- }\r
- else if (false == newPconf->edp)\r
- {\r
- gPconf->edp = false;\r
- }\r
- else\r
- {\r
- ehRet = OC_EH_ERROR;\r
- }\r
-\r
- // Update storage\r
- if(OC_EH_ERROR != ehRet && true == UpdatePersistentStorage(gPconf))\r
- {\r
- ehRet = OC_EH_RESOURCE_CREATED;\r
- }\r
-\r
- DeletePconfBinData(newPconf);\r
- }\r
- else\r
- {\r
- ehRet = OC_EH_ERROR;\r
- }\r
-\r
- // Send payload to request originator\r
- SendSRMResponse(ehRequest, ehRet, NULL);\r
-\r
- OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);\r
- return ehRet;\r
-}\r
-\r
-/*\r
- * This internal method is the entity handler for PCONF resources and\r
- * will handle REST request (POST) for them.\r
- */\r
-OCEntityHandlerResult PconfEntityHandler (OCEntityHandlerFlag flag,\r
- OCEntityHandlerRequest * ehRequest,\r
- void* callbackParameter)\r
-{\r
- OIC_LOG(DEBUG, TAG, "Received request PconfEntityHandler");\r
- (void)callbackParameter;\r
- OCEntityHandlerResult ehRet = OC_EH_ERROR;\r
-\r
- if (!ehRequest)\r
- {\r
- return ehRet;\r
- }\r
-\r
- if (flag & OC_REQUEST_FLAG)\r
- {\r
- OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");\r
- switch (ehRequest->method)\r
- {\r
- case OC_REST_GET:\r
- ehRet = HandlePconfGetRequest(ehRequest);\r
- break;\r
-\r
- case OC_REST_POST:\r
- ehRet = HandlePconfPostRequest(ehRequest);\r
- break;\r
-\r
- case OC_REST_DELETE:\r
- break;\r
-\r
- default:\r
- ehRet = OC_EH_ERROR;\r
- SendSRMResponse(ehRequest, ehRet, NULL);\r
- }\r
- }\r
-\r
- return ehRet;\r
-}\r
-\r
-/*\r
- * This internal method is used to create '/oic/sec/pconf' resource.\r
- */\r
-OCStackResult CreatePconfResource()\r
-{\r
- OCStackResult ret;\r
-\r
- ret = OCCreateResource(&gPconfHandle,\r
- OIC_RSRC_TYPE_SEC_PCONF,\r
- OIC_MI_DEF,\r
- OIC_RSRC_PCONF_URI,\r
- PconfEntityHandler,\r
- NULL,\r
- OC_SECURE | OC_EXPLICIT_DISCOVERABLE);\r
-\r
- if (OC_STACK_OK != ret)\r
- {\r
- OIC_LOG (ERROR, TAG, "Unable to instantiate PCONF resource");\r
- DeInitPconfResource();\r
- }\r
- return ret;\r
-}\r
-\r
-/**\r
- * Get the default value.\r
- * @retval the gDefaultPconf pointer;\r
- */\r
-static OicSecPconf_t* GetPconfDefault()\r
-{\r
- OIC_LOG (DEBUG, TAG, "GetPconfDefault");\r
-\r
- return &gDefaultPconf;\r
-}\r
-\r
-/**\r
- * This method is used by SRM to retrieve PCONF resource data..\r
- *\r
- * @retval reference to @ref OicSecPconf_t, binary format of Pconf resource data\r
- */\r
-const OicSecPconf_t* GetPconfResourceData()\r
-{\r
- return gPconf;\r
-}\r
-\r
-/**\r
- * Initialize PCONF resource by loading data from persistent storage.\r
- *\r
- * @retval OC_STACK_OK for Success, otherwise some error value\r
- */\r
-OCStackResult InitPconfResource()\r
-{\r
- OCStackResult ret = OC_STACK_ERROR;\r
-\r
- // Read PCONF resource from PS\r
- char* jsonSVRDatabase = GetSVRDatabase();\r
-\r
- if (jsonSVRDatabase)\r
- {\r
- // Convert JSON PCONF into binary format\r
- gPconf = JSONToPconfBin(jsonSVRDatabase);\r
- }\r
-\r
- if(!jsonSVRDatabase || !gPconf)\r
- {\r
- gPconf = GetPconfDefault();\r
-\r
- // device id from doxm\r
- OicUuid_t deviceId = {.id = {0}};\r
- OCStackResult ret = GetDoxmDeviceID( &deviceId);\r
- VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);\r
- memcpy(&gPconf->deviceID, &deviceId, sizeof(OicUuid_t));\r
- }\r
- VERIFY_NON_NULL(TAG, gPconf, ERROR);\r
-\r
- // Instantiate 'oic.sec.pconf'\r
- ret = CreatePconfResource();\r
-\r
-exit:\r
- if (OC_STACK_OK != ret)\r
- {\r
- DeInitPconfResource();\r
- }\r
- OICFree(jsonSVRDatabase);\r
- return ret;\r
-}\r
-\r
-/**\r
- * Perform cleanup for PCONF resources.\r
- *\r
- * @return\r
- * OC_STACK_OK - no error\r
- * OC_STACK_ERROR - stack process error\r
- *\r
- */\r
-OCStackResult DeInitPconfResource()\r
-{\r
- OCStackResult ret = OCDeleteResource(gPconfHandle);\r
- if(gPconf!= &gDefaultPconf)\r
- {\r
- DeletePconfBinData(gPconf);\r
- }\r
- gPconf = NULL;\r
-\r
- if(OC_STACK_OK == ret)\r
- {\r
- return OC_STACK_OK;\r
- }\r
- else\r
- {\r
- return OC_STACK_ERROR;\r
- }\r
-}\r
-\r
-/**\r
- * This method might be used to add a paired device id after direct-pairing process complete.\r
- *\r
- * @param pdeviceId ID of the paired device.\r
- *\r
- * @retval OC_STACK_OK for Success, otherwise some error value\r
- */\r
-OCStackResult AddPairedDevice(OicUuid_t *pdeviceId)\r
-{\r
- if (!gPconf || !pdeviceId)\r
- {\r
- return OC_STACK_INVALID_PARAM;\r
- }\r
-\r
-\r
- OicUuid_t *prevList = gPconf->pddevs;\r
- gPconf->pddevs = (OicUuid_t *)OICCalloc(gPconf->pddevLen+1, sizeof(OicUuid_t));\r
- if(!gPconf->pddevs)\r
- {\r
- return OC_STACK_NO_MEMORY;\r
- }\r
- for (size_t i=0; i<gPconf->pddevLen; i++)\r
- {\r
- memcpy(&gPconf->pddevs[i], &prevList[i], sizeof(OicUuid_t));\r
- }\r
-\r
- // add new paired device id\r
- memcpy(&gPconf->pddevs[gPconf->pddevLen], pdeviceId, sizeof(OicUuid_t));\r
- gPconf->pddevLen++;\r
-\r
- // Update storage\r
- if(true != UpdatePersistentStorage(gPconf))\r
- {\r
- OIC_LOG (ERROR, TAG, "Fail to update pconf resource");\r
- return OC_STACK_ERROR;\r
- }\r
-\r
- OIC_LOG (ERROR, TAG, "Add paired device success");\r
- return OC_STACK_OK;\r
-}\r
-\r
-/**\r
- * This method might be used by PolicyEngine to retrieve PDACL for a Subject.\r
- *\r
- * @param subjectId ID of the subject for which PDACL is required.\r
- * @param savePtr is used internally by @ref GetACLResourceData to maintain index between\r
- * successive calls for same subjectId.\r
- *\r
- * @retval reference to @ref OicSecPdAcl_t if PDACL is found, else NULL\r
- */\r
-const OicSecPdAcl_t* GetPdAclData(const OicUuid_t* subjectId, OicSecPdAcl_t **savePtr)\r
-{\r
- OicSecPdAcl_t *pdacl = NULL;\r
-\r
- if ( NULL == subjectId)\r
- {\r
- return NULL;\r
- }\r
-\r
- /*\r
- * savePtr MUST point to NULL if this is the 'first' call to retrieve PDACL for\r
- * subjectID.\r
- */\r
- if (NULL == *savePtr)\r
- {\r
- pdacl = gPconf->pdacls;\r
-\r
- // Find if 'subjectID' is in paired device list.\r
- for(size_t i=0; i<gPconf->pddevLen; i++)\r
- {\r
- if (memcmp(&(gPconf->pddevs[i]), subjectId, sizeof(OicUuid_t)) == 0)\r
- {\r
- *savePtr = pdacl;\r
- return pdacl;\r
- }\r
- }\r
- }\r
- else\r
- {\r
- OicSecPdAcl_t *temp = NULL;\r
-\r
- /*\r
- * If this is a 'successive' call, search for location pointed by\r
- * savePtr and assign 'begin' to the next PDACL after it in the linked\r
- * list and start searching from there.\r
- */\r
- LL_FOREACH(gPconf->pdacls, temp)\r
- {\r
- if (temp == *savePtr)\r
- {\r
- pdacl = temp->next;\r
- *savePtr = pdacl;\r
- return pdacl;\r
- }\r
- }\r
- }\r
-\r
- // Cleanup in case no PDACL is found\r
- *savePtr = NULL;\r
- return NULL;\r
-}\r
-\r
-/**\r
- * This method return whether device is paired or not.\r
- *\r
- * @param pdeviceId Target device ID to find in paired list.\r
- * @retval ture if device is already paired, else false\r
- */\r
-bool IsPairedDevice(const OicUuid_t* pdeviceId)\r
-{\r
- // Find if 'pdeviceId' is in paired device list.\r
- for(size_t i=0; i<gPconf->pddevLen; i++)\r
- {\r
- if (memcmp(&(gPconf->pddevs[i]), pdeviceId, sizeof(OicUuid_t)) == 0)\r
- {\r
- return true;\r
- }\r
- }\r
- return false;\r
-}\r
-\r
-\r
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include "ocstack.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "cJSON.h"
+#include "base64.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
+#include "resourcemanager.h"
+#include "pconfresource.h"
+#include "psinterface.h"
+#include "utlist.h"
+#include "srmresourcestrings.h"
+#include "doxmresource.h"
+#include "srmutility.h"
+#include "ocserverrequest.h"
+#include <stdlib.h>
+#include "psinterface.h"
+#include "security_internals.h"
+#ifdef WITH_ARDUINO
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#define TAG "SRM-PCONF"
+
+static const uint16_t CBOR_SIZE = 1024;
+static const uint64_t CBOR_MAX_SIZE = 4400;
+static const uint8_t PCONF_MAP_SIZE = 4;
+static const uint8_t PCONF_RESOURCE_MAP_SIZE = 4;
+
+static OicSecPconf_t *gPconf = NULL;
+static OCResourceHandle gPconfHandle = NULL;
+static OicSecPconf_t gDefaultPconf =
+{
+ false, /* bool edp */
+ NULL, /* OicSecPrm *prm */
+ 0, /* size_t prmLen */
+ {.val = {0}}, /* OicDpPin_t pin */
+ NULL, /* OicSecPdAcl_t *pdacls */
+ NULL, /* OicUuid_t *pddevs */
+ 0, /* size_t pddevLen */
+ {.id = {0}}, /* OicUuid_t deviceID */
+ {.id = {0}}, /* OicUuid_t rowner */
+};
+
+/**
+ * This function frees OicSecPdAcl_t object's fields and object itself.
+ */
+void FreePdAclList(OicSecPdAcl_t* pdacls)
+{
+ if (pdacls)
+ {
+ size_t i = 0;
+
+ //Clean pdacl objecs
+ OicSecPdAcl_t *aclTmp1 = NULL;
+ OicSecPdAcl_t *aclTmp2 = NULL;
+ LL_FOREACH_SAFE(pdacls, aclTmp1, aclTmp2)
+ {
+ LL_DELETE(pdacls, aclTmp1);
+
+ // Clean Resources
+ for (i = 0; i < aclTmp1->resourcesLen; i++)
+ {
+ OICFree(aclTmp1->resources[i]);
+ }
+ OICFree(aclTmp1->resources);
+
+ //Clean Period
+ if(aclTmp1->periods)
+ {
+ for(i = 0; i < aclTmp1->prdRecrLen; i++)
+ {
+ OICFree(aclTmp1->periods[i]);
+ }
+ OICFree(aclTmp1->periods);
+ }
+
+ //Clean Recurrence
+ if(aclTmp1->recurrences)
+ {
+ for(i = 0; i < aclTmp1->prdRecrLen; i++)
+ {
+ OICFree(aclTmp1->recurrences[i]);
+ }
+ OICFree(aclTmp1->recurrences);
+ }
+ }
+
+ //Clean pconf itself
+ OICFree(pdacls);
+ }
+}
+
+void DeletePconfBinData(OicSecPconf_t* pconf)
+{
+ if (pconf)
+ {
+ //Clean prm
+ OICFree(pconf->prm);
+
+ //Clean pdacl
+ if (pconf->pdacls)
+ {
+ FreePdAclList(pconf->pdacls);
+ }
+
+ //Clean pddev
+ OICFree(pconf->pddevs);
+
+ //Clean pconf itself
+ OICFree(pconf);
+ }
+}
+
+static size_t OicPdAclSize(const OicSecPdAcl_t *pdAcl)
+{
+ if (!pdAcl)
+ {
+ return 0;
+ }
+
+ OicSecPdAcl_t *tmp = (OicSecPdAcl_t *)pdAcl;
+ size_t size = 0;
+ while (tmp)
+ {
+ size++;
+ tmp = tmp->next;
+ }
+ return size;
+}
+
+OCStackResult PconfToCBORPayload(const OicSecPconf_t *pconf,uint8_t **payload,size_t *size)
+{
+ if (NULL == pconf || NULL == payload || NULL != *payload || NULL == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ size_t cborLen = *size;
+ if(0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
+ }
+ *payload = NULL;
+
+ OCStackResult ret = OC_STACK_ERROR;
+ CborEncoder encoder;
+ CborEncoder pconfMap;
+
+ int64_t cborEncoderResult = CborNoError;
+ uint8_t mapSize = PCONF_MAP_SIZE;
+
+ if (pconf->prmLen > 0)
+ {
+ mapSize++;
+ }
+ if (pconf->pdacls)
+ {
+ mapSize++;
+ }
+ if (pconf->pddevs)
+ {
+ mapSize++;
+ }
+
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &pconfMap, mapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating Pconf Map.");
+
+ //edp -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_EDP_NAME,
+ strlen(OIC_JSON_EDP_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Encode EDP String.");
+ cborEncoderResult = cbor_encode_boolean(&pconfMap, pconf->edp);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert PconfEDP value");
+
+ //PRM type -- Not Mandatory
+ if(pconf->prmLen > 0)
+ {
+ CborEncoder prm;
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PRM_NAME,
+ strlen(OIC_JSON_PRM_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM NAME");
+ cborEncoderResult = cbor_encoder_create_array(&pconfMap, &prm, pconf->prmLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM value");
+
+ for (size_t i = 0; i < pconf->prmLen; i++)
+ {
+ cborEncoderResult = cbor_encode_int(&prm, pconf->prm[i]);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Convert Pconf PRM Array");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&pconfMap, &prm);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close encode array");
+ }
+
+ //PIN -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PIN_NAME,
+ strlen(OIC_JSON_PIN_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create OIC_JSON_PIN_NAME");
+ cborEncoderResult = cbor_encode_byte_string(&pconfMap, pconf->pin.val, sizeof(pconf->pin.val));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to convert pin value");
+
+ //PDACL -- Mandatory
+ if (pconf->pdacls)
+ {
+ OicSecPdAcl_t *pdacl = pconf->pdacls;
+ CborEncoder pdAclArray;
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDACL_NAME,
+ strlen(OIC_JSON_PDACL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create OIC_JSON_PDACL_NAME");
+ cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pdAclArray,
+ OicPdAclSize(pconf->pdacls));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to creeate _pdacl array");
+
+ while(pdacl)
+ {
+ CborEncoder pdAclMap;
+ // PDACL Map size - Number of mandatory items
+ uint8_t aclMapSize = 2;
+
+ if (pdacl->prdRecrLen)
+ {
+ ++aclMapSize;
+ }
+ if (pdacl->recurrences)
+ {
+ ++aclMapSize;
+ }
+
+ cborEncoderResult = cbor_encoder_create_map(&pdAclArray, &pdAclMap, aclMapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to creeate _pdacl array");
+
+ // Resources -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RESOURCES_NAME,
+ strlen(OIC_JSON_RESOURCES_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode resource result");
+
+ CborEncoder resources;
+ cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &resources,
+ pdacl->resourcesLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create resource array");
+
+ for (size_t i = 0; i < pdacl->resourcesLen; i++)
+ {
+ CborEncoder rMap;
+ cborEncoderResult = cbor_encoder_create_map(&resources, &rMap,
+ PCONF_RESOURCE_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding Resource Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_HREF_NAME,
+ strlen(OIC_JSON_HREF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Name Tag.");
+ cborEncoderResult = cbor_encode_text_string(&rMap, pdacl->resources[i],
+ strlen(pdacl->resources[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding HREF Value in Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_REL_NAME,
+ strlen(OIC_JSON_REL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Name Tag.");
+
+ // TODO : Need to assign real value of REL
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
+ strlen(OIC_JSON_EMPTY_STRING));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding REL Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_RT_NAME,
+ strlen(OIC_JSON_RT_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
+
+ // TODO : Need to assign real value of RT
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
+ strlen(OIC_JSON_EMPTY_STRING));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_IF_NAME,
+ strlen(OIC_JSON_IF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
+
+ // TODO : Need to assign real value of IF
+ cborEncoderResult = cbor_encode_text_string(&rMap, OIC_JSON_EMPTY_STRING,
+ strlen(OIC_JSON_EMPTY_STRING));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
+
+ cborEncoderResult = cbor_encoder_close_container(&resources, &rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Resource Map.");
+ }
+
+ cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close resource array");
+
+ // Permissions -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERMISSION_NAME,
+ strlen(OIC_JSON_PERMISSION_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create permition string");
+ cborEncoderResult = cbor_encode_int(&pdAclMap, pdacl->permission);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode permition calue");
+
+ // Period -- Not Mandatory
+ if (pdacl->periods)
+ {
+ CborEncoder period;
+ cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_PERIODS_NAME,
+ strlen(OIC_JSON_PERIODS_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period value");
+ cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &period,
+ pdacl->prdRecrLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
+
+ for (size_t i = 0; i < pdacl->prdRecrLen; i++)
+ {
+ cborEncoderResult = cbor_encode_text_string(&period, pdacl->periods[i],
+ strlen(pdacl->periods[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode period");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &period);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to close period array");
+ }
+
+ // Period -- Not Mandatory
+ if(0 != pdacl->prdRecrLen && pdacl->recurrences)
+ {
+ CborEncoder recurrences;
+ cborEncoderResult = cbor_encode_text_string(&pdAclMap, OIC_JSON_RECURRENCES_NAME,
+ strlen(OIC_JSON_RECURRENCES_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult,"Failed to encode recurrences");
+ cborEncoderResult = cbor_encoder_create_array(&pdAclMap, &recurrences,
+ pdacl->prdRecrLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create rec array");
+
+ for (size_t i = 0; i < pdacl->prdRecrLen; i++)
+ {
+ cborEncoderResult = cbor_encode_text_string(&recurrences,
+ pdacl->recurrences[i], strlen(pdacl->recurrences[i]));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode recurrences");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&pdAclMap, &recurrences);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close rec array");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&pdAclArray, &pdAclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl map");
+
+ pdacl = pdacl->next;
+ }
+ //clsoe the array
+ cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pdAclArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close acl array");
+ }
+
+ //PDDev -- Mandatory
+ //There may not be paired devices if it did not pairing before
+ if (pconf->pddevs && 0 < pconf->pddevLen)
+ {
+ CborEncoder pddev;
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_PDDEV_LIST_NAME,
+ strlen(OIC_JSON_PDDEV_LIST_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode pddev");
+ cborEncoderResult = cbor_encoder_create_array(&pconfMap, &pddev, pconf->pddevLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to create array");
+
+ for (size_t i = 0; i < pconf->pddevLen; i++)
+ {
+ char *pddevId = NULL;
+ ret = ConvertUuidToStr(&pconf->pddevs[i], &pddevId);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&pddev, pddevId, strlen(pddevId));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding pddev Id Value.");
+ OICFree(pddevId);
+ }
+ cborEncoderResult = cbor_encoder_close_container(&pconfMap, &pddev);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pddev array");
+ }
+
+ //DeviceId -- Mandatory
+ //There may not be devicd id if caller is provisoning tool
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_DEVICE_ID_NAME,
+ strlen(OIC_JSON_DEVICE_ID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode device id");
+ {
+ char *deviceId = NULL;
+ ret = ConvertUuidToStr(&pconf->deviceID, &deviceId);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, deviceId, strlen(deviceId));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode deviceID value");
+ OICFree(deviceId);
+ }
+
+ //ROwner -- Mandatory
+ {
+ char *rowner = NULL;
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_ROWNERID_NAME,
+ strlen(OIC_JSON_ROWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rowner string");
+ ret = ConvertUuidToStr(&pconf->rownerID, &rowner);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ cborEncoderResult = cbor_encode_text_string(&pconfMap, rowner, strlen(rowner));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode rwoner value");
+ OICFree(rowner);
+ }
+
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &pconfMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to close pconfMap");
+
+ *size = encoder.ptr - outPayload;
+ *payload = outPayload;
+ ret = OC_STACK_OK;
+exit:
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+ {
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = PconfToCBORPayload(pconf, payload, &cborLen);
+ *size = cborLen;
+ }
+ if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *payload = NULL;
+ *size = 0;
+ ret = OC_STACK_ERROR;
+ }
+ return ret;
+}
+
+OCStackResult CBORPayloadToPconf(const uint8_t *cborPayload, size_t size, OicSecPconf_t **secPconf)
+{
+ if (NULL == cborPayload || NULL == secPconf || NULL != *secPconf || 0 == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ OCStackResult ret = OC_STACK_ERROR;
+ *secPconf = NULL;
+ CborValue pconfCbor = { .parser = NULL };
+ CborParser parser = { .end = NULL };
+ CborError cborFindResult = CborNoError;
+
+ cbor_parser_init(cborPayload, size, 0, &parser, &pconfCbor);
+ CborValue pconfMap = { .parser = NULL } ;
+ OicSecPconf_t *pconf = NULL;
+ cborFindResult = cbor_value_enter_container(&pconfCbor, &pconfMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter map");
+ pconf = (OicSecPconf_t *)OICCalloc(1, sizeof(*pconf));
+ VERIFY_NON_NULL(TAG, pconf, ERROR);
+ while (cbor_value_is_valid(&pconfMap))
+ {
+ char *name = NULL;
+ size_t len = 0;
+ CborType type = cbor_value_get_type(&pconfMap);
+ if (type == CborTextStringType)
+ {
+ cborFindResult = cbor_value_dup_text_string(&pconfMap, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
+ cborFindResult = cbor_value_advance(&pconfMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+ }
+
+ if (name)
+ {
+ //EDP -- Mandatory
+ if(0 == strcmp(OIC_JSON_EDP_NAME, name))
+ {
+ cborFindResult = cbor_value_get_boolean(&pconfMap, &pconf->edp);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
+ }
+ if (0 == strcmp(OIC_JSON_PRM_NAME, name))
+ {
+ int i = 0;
+ CborValue prm = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->prmLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
+ VERIFY_SUCCESS(TAG, pconf->prmLen != 0, ERROR);
+
+ pconf->prm = (OicSecPrm_t *)OICCalloc(pconf->prmLen, sizeof(OicSecPrm_t));
+ VERIFY_NON_NULL(TAG, pconf->prm, ERROR);
+ cborFindResult = cbor_value_enter_container(&pconfMap, &prm);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to eneter array");
+
+ while (cbor_value_is_valid(&prm))
+ {
+ cborFindResult = cbor_value_get_int(&prm, (int *)&pconf->prm[i++]);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
+ cborFindResult = cbor_value_advance(&prm);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+ }
+ }
+ //PIN -- Mandatory
+ if (0 == strcmp(OIC_JSON_PIN_NAME, name))
+ {
+ uint8_t *pin = NULL;
+ cborFindResult = cbor_value_dup_byte_string(&pconfMap, &pin, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
+ memcpy(pconf->pin.val, pin, len);
+ OICFree(pin);
+ }
+
+ //PDACL -- Mandatory
+ if (0 == strcmp(OIC_JSON_PDACL_NAME, name))
+ {
+ CborValue pdAclArray = { .parser = NULL};
+ OicSecPdAcl_t *headPdacl = NULL;
+
+ cborFindResult = cbor_value_enter_container(&pconfMap, &pdAclArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
+
+ while (cbor_value_is_valid(&pdAclArray))
+ {
+ CborValue pdAclMap = { .parser = NULL};
+ OicSecPdAcl_t *pdacl = (OicSecPdAcl_t *) OICCalloc(1, sizeof(OicSecPdAcl_t));
+ VERIFY_NON_NULL(TAG, pdacl, ERROR);
+
+ cborFindResult = cbor_value_enter_container(&pdAclArray, &pdAclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
+
+ while (cbor_value_is_valid(&pdAclMap))
+ {
+ char* name = NULL;
+ size_t len = 0;
+ CborType type = cbor_value_get_type(&pdAclMap);
+ if (type == CborTextStringType)
+ {
+ cborFindResult = cbor_value_dup_text_string(&pdAclMap, &name,
+ &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+ cborFindResult = cbor_value_advance(&pdAclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+ }
+ if (name)
+ {
+ // Resources -- Mandatory
+ if (strcmp(name, OIC_JSON_RESOURCES_NAME) == 0)
+ {
+ int i = 0;
+ CborValue resources = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&pdAclMap,
+ &pdacl->resourcesLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
+ cborFindResult = cbor_value_enter_container(&pdAclMap, &resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
+ pdacl->resources = (char **) OICCalloc(pdacl->resourcesLen,
+ sizeof(char*));
+ VERIFY_NON_NULL(TAG, pdacl->resources, ERROR);
+
+ while (cbor_value_is_valid(&resources))
+ {
+ CborValue rMap = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&resources, &rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Entering Resource Map");
+
+ while(cbor_value_is_valid(&rMap))
+ {
+ char *rMapName = NULL;
+ size_t rMapNameLen = 0;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &rMapName, &rMapNameLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Name Tag.");
+ cborFindResult = cbor_value_advance(&rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RMap Data Value.");
+
+ // "href"
+ if (0 == strcmp(OIC_JSON_HREF_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecPdAcl_t based on RAML spec.
+ cborFindResult = cbor_value_dup_text_string(&rMap, &pdacl->resources[i++], &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Href Value.");
+ }
+
+ // "rel"
+ if (0 == strcmp(OIC_JSON_REL_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
+ char *relData = NULL;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &relData, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding REL Value.");
+ OICFree(relData);
+ }
+
+ // "rt"
+ if (0 == strcmp(OIC_JSON_RT_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
+ char *rtData = NULL;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &rtData, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding RT Value.");
+ OICFree(rtData);
+ }
+
+ // "if"
+ if (0 == strcmp(OIC_JSON_IF_NAME, rMapName))
+ {
+ // TODO : Need to check data structure of OicSecPdAcl_t and assign based on RAML spec.
+ char *ifData = NULL;
+ cborFindResult = cbor_value_dup_text_string(&rMap, &ifData, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding IF Value.");
+ OICFree(ifData);
+ }
+
+ if (cbor_value_is_valid(&rMap))
+ {
+ cborFindResult = cbor_value_advance(&rMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Rlist Map.");
+ }
+ OICFree(rMapName);
+ }
+
+ if (cbor_value_is_valid(&resources))
+ {
+ cborFindResult = cbor_value_advance(&resources);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
+ }
+ }
+ }
+
+ // Permissions -- Mandatory
+ if (strcmp(name, OIC_JSON_PERMISSION_NAME) == 0)
+ {
+ cborFindResult = cbor_value_get_uint64(&pdAclMap,
+ (uint64_t *) &pdacl->permission);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
+ }
+
+ // Period -- Not mandatory
+ if (strcmp(name, OIC_JSON_PERIODS_NAME) == 0)
+ {
+ int i = 0;
+ CborValue period = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&pdAclMap,
+ &pdacl->prdRecrLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
+ cborFindResult = cbor_value_enter_container(&pdAclMap, &period);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
+ pdacl->periods = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
+ VERIFY_NON_NULL(TAG, pdacl->periods, ERROR);
+
+ while (cbor_value_is_text_string(&period))
+ {
+ cborFindResult = cbor_value_dup_text_string(&period,
+ &pdacl->periods[i++], &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+ cborFindResult = cbor_value_advance(&period);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
+ pdacl->prdRecrLen++;
+ }
+ }
+
+ // Recurrence -- Not mandatory
+ if (strcmp(name, OIC_JSON_RECURRENCES_NAME) == 0)
+ {
+ int i = 0;
+ CborValue recurrences = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&pdAclMap, &pdacl->prdRecrLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
+ cborFindResult = cbor_value_enter_container(&pdAclMap, &recurrences);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
+ pdacl->recurrences = (char **) OICCalloc(pdacl->prdRecrLen, sizeof(char*));
+ VERIFY_NON_NULL(TAG, pdacl->recurrences, ERROR);
+
+ while (cbor_value_is_text_string(&recurrences))
+ {
+ cborFindResult = cbor_value_dup_text_string(&recurrences,
+ &pdacl->recurrences[i++], &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
+ cborFindResult = cbor_value_advance(&recurrences);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
+ }
+ }
+ if (type != CborMapType && cbor_value_is_valid(&pdAclMap))
+ {
+ cborFindResult = cbor_value_advance(&pdAclMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
+ }
+ }
+ if (cbor_value_is_valid(&pdAclArray))
+ {
+ cborFindResult = cbor_value_advance(&pdAclArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
+ }
+ OICFree(name);
+ name = NULL;
+ }
+ pdacl->next = NULL;
+ if (headPdacl == NULL)
+ {
+ headPdacl = pdacl;
+ }
+ else
+ {
+ OicSecPdAcl_t *temp = headPdacl;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = pdacl;
+ }
+ }
+ pconf->pdacls = headPdacl;
+ }
+
+ //PDDev -- Mandatory
+ if (strcmp(name, OIC_JSON_PDDEV_LIST_NAME) == 0)
+ {
+ int i = 0;
+ CborValue pddevs = { .parser = NULL };
+ cborFindResult = cbor_value_get_array_length(&pconfMap, &pconf->pddevLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get length");
+ cborFindResult = cbor_value_enter_container(&pconfMap, &pddevs);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to enter");
+
+ pconf->pddevs = (OicUuid_t *)OICMalloc(pconf->pddevLen * sizeof(OicUuid_t));
+ VERIFY_NON_NULL(TAG, pconf->pddevs, ERROR);
+ while (cbor_value_is_valid(&pddevs))
+ {
+ char *pddev = NULL;
+ cborFindResult = cbor_value_dup_text_string(&pddevs, &pddev, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get value");
+ cborFindResult = cbor_value_advance(&pddevs);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
+ ret = ConvertStrToUuid(pddev, &pconf->pddevs[i++]);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(pddev);
+ }
+ }
+
+ //Mandatory - Device Id
+ if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name))
+ {
+ char *deviceId = NULL;
+ cborFindResult = cbor_value_dup_text_string(&pconfMap, &deviceId, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get deviceID");
+ ret = ConvertStrToUuid(deviceId, &pconf->deviceID);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(deviceId);
+ }
+
+ // ROwner -- Mandatory
+ if (0 == strcmp(OIC_JSON_ROWNERID_NAME, name))
+ {
+ char *rowner = NULL;
+ cborFindResult = cbor_value_dup_text_string(&pconfMap, &rowner, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get rowner");
+ ret = ConvertStrToUuid(rowner, &pconf->rownerID);
+ VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
+ OICFree(rowner);
+ }
+ }
+ if (CborMapType != type && cbor_value_is_valid(&pconfMap))
+ {
+ cborFindResult = cbor_value_advance(&pconfMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance");
+ }
+ OICFree(name);
+ name = NULL;
+ }
+ *secPconf=pconf;
+ ret = OC_STACK_OK;
+exit:
+ if (CborNoError != cborFindResult)
+ {
+ OIC_LOG (ERROR, TAG, "CBORPayloadToPconf failed");
+ DeletePconfBinData(pconf);
+ pconf = NULL;
+ *secPconf = NULL;
+ ret = OC_STACK_ERROR;
+ }
+ return ret;
+}
+
+static bool UpdatePersistentStorage(const OicSecPconf_t * pconf)
+{
+ bool ret = false;
+
+ // Convert PCONF data into Cborpayload for update to persistent storage
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ if (OC_STACK_OK == PconfToCBORPayload(pconf, &payload, &size) && NULL !=payload)
+ {
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, payload, size))
+ {
+ ret = true;
+ }
+ OICFree(payload);
+ }
+ return ret;
+}
+
+static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest * ehRequest)
+{
+ uint8_t* payload = NULL;
+ size_t size = 0;
+ OCEntityHandlerResult ehRet = OC_EH_OK;
+
+ OicSecPconf_t pconf;
+ memset(&pconf, 0, sizeof(OicSecPconf_t));
+
+ OIC_LOG (DEBUG, TAG, "Pconf EntityHandle processing GET request");
+
+ if (true == GetDoxmResourceData()->dpc)
+ {
+ //Making response elements for Get request
+ if( (true == gPconf->edp) &&
+ (gPconf->prm && 0 < gPconf->prmLen) &&
+ (0 < strlen((const char*)gPconf->deviceID.id)) &&
+ (0 < strlen((const char*)gPconf->rownerID.id)))
+ {
+ pconf.edp = true;
+ pconf.prm = gPconf->prm;
+ pconf.prmLen = gPconf->prmLen;
+ memcpy(&pconf.deviceID, &gPconf->deviceID, sizeof(OicUuid_t));
+ memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
+ OIC_LOG (DEBUG, TAG, "PCONF - direct pairing enabled");
+ }
+ else if (false == gPconf->edp)
+ {
+ pconf.edp = false;
+ memcpy(&pconf.rownerID, &gPconf->rownerID, sizeof(OicUuid_t));
+ OIC_LOG (DEBUG, TAG, "PCONF - direct pairing disable");
+ }
+ else
+ {
+ ehRet= OC_EH_ERROR;
+ OIC_LOG (DEBUG, TAG, "PCONF - error");
+ }
+ }
+ else
+ {
+ OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
+ }
+
+
+ if (OC_STACK_OK != PconfToCBORPayload(gPconf, &payload, &size))
+ {
+ ehRet = OC_EH_ERROR;
+ }
+
+ if(OC_EH_OK == ehRet)
+ {
+ ehRet = (payload ? OC_EH_OK : OC_EH_ERROR);
+ }
+ else
+ {
+ OICFree(payload);
+ payload = NULL;
+ size = 0;
+ }
+
+ // Send response payload to request originator
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfGetRequest");
+ }
+ OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__, ehRet);
+
+ OICFree(payload);
+ return ehRet;
+}
+
+static OCEntityHandlerResult HandlePconfPostRequest (const OCEntityHandlerRequest * ehRequest)
+{
+ OCEntityHandlerResult ehRet = OC_EH_OK;
+ OCStackResult res=OC_STACK_OK;
+ OicSecPconf_t* newPconf = NULL;
+
+ if (true == GetDoxmResourceData()->dpc)
+ {
+ // Convert CBOR PCONF data into binary. This will also validate the PCONF data received.
+ uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
+
+ if(payload){
+ res = CBORPayloadToPconf(payload, size, &newPconf);
+ }
+ }
+ else
+ {
+ OIC_LOG (DEBUG, TAG, "DPC == false : Direct-Pairing Disabled");
+ ehRet = OC_EH_ERROR;
+ }
+
+ if (newPconf && res == OC_STACK_OK)
+ {
+ // Check if valid Post request
+ if ((true == newPconf->edp) && (0 < newPconf->prmLen) &&
+ DP_PIN_LENGTH == sizeof(newPconf->pin.val))
+ {
+ OicSecPrm_t *oldPrm = gPconf->prm;
+ OicSecPdAcl_t *oldPdacl = gPconf->pdacls;
+
+ // Update local PCONF with new PCONF
+ gPconf->edp = true;
+ memcpy(&gPconf->pin, &newPconf->pin, sizeof(OicDpPin_t));
+ gPconf->prm = newPconf->prm;
+ gPconf->prmLen = newPconf->prmLen;
+ gPconf->pdacls = newPconf->pdacls;
+ memcpy(&gPconf->rownerID, &newPconf->rownerID, sizeof(OicUuid_t));
+
+ // to delete old value(prm, pdacl)
+ newPconf->prm = oldPrm;
+ newPconf->pdacls = oldPdacl;
+ }
+ else if (false == newPconf->edp)
+ {
+ gPconf->edp = false;
+ }
+ else
+ {
+ ehRet = OC_EH_ERROR;
+ }
+
+ // Update storage
+ if(OC_EH_ERROR != ehRet && true == UpdatePersistentStorage(gPconf))
+ {
+ ehRet = OC_EH_RESOURCE_CREATED;
+ }
+
+ DeletePconfBinData(newPconf);
+ }
+ else
+ {
+ ehRet = OC_EH_ERROR;
+ }
+
+ // Send payload to request originator
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePconfPostRequest");
+ }
+
+ OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
+ return ehRet;
+}
+
+/*
+ * This internal method is the entity handler for PCONF resources and
+ * will handle REST request (POST) for them.
+ */
+OCEntityHandlerResult PconfEntityHandler (OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void* callbackParameter)
+{
+ OIC_LOG(DEBUG, TAG, "Received request PconfEntityHandler");
+ (void)callbackParameter;
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+ if (!ehRequest)
+ {
+ return ehRet;
+ }
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
+ switch (ehRequest->method)
+ {
+ case OC_REST_GET:
+ ehRet = HandlePconfGetRequest(ehRequest);
+ break;
+
+ case OC_REST_POST:
+ ehRet = HandlePconfPostRequest(ehRequest);
+ break;
+
+ case OC_REST_DELETE:
+ break;
+
+ default:
+ ehRet = OC_EH_ERROR;
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
+ }
+ }
+
+ return ehRet;
+}
+
+/*
+ * This internal method is used to create '/oic/sec/pconf' resource.
+ */
+OCStackResult CreatePconfResource()
+{
+ OCStackResult ret;
+
+ ret = OCCreateResource(&gPconfHandle,
+ OIC_RSRC_TYPE_SEC_PCONF,
+ OIC_MI_DEF,
+ OIC_RSRC_PCONF_URI,
+ PconfEntityHandler,
+ NULL,
+ OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
+
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Unable to instantiate PCONF resource");
+ DeInitPconfResource();
+ }
+ return ret;
+}
+
+/**
+ * Get the default value.
+ * @retval the gDefaultPconf pointer;
+ */
+static OicSecPconf_t* GetPconfDefault()
+{
+ OIC_LOG (DEBUG, TAG, "GetPconfDefault");
+
+ return &gDefaultPconf;
+}
+
+/**
+ * This method is used by SRM to retrieve PCONF resource data..
+ *
+ * @retval reference to @ref OicSecPconf_t, binary format of Pconf resource data
+ */
+const OicSecPconf_t* GetPconfResourceData()
+{
+ return gPconf;
+}
+
+/**
+ * Initialize PCONF resource by loading data from persistent storage.
+ *
+ * @retval OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InitPconfResource()
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ uint8_t *data = NULL;
+ size_t size = 0;
+
+ ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PCONF_NAME, &data, &size);
+ // If database read failed
+ if (ret != OC_STACK_OK)
+ {
+ OIC_LOG(DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
+ if (data)
+ {
+ CBORPayloadToPconf(data, size, &gPconf);
+ }
+
+ if (!data || !gPconf)
+ {
+ gPconf = GetPconfDefault();
+
+ // device id from doxm
+ OicUuid_t deviceId = {.id = {0}};
+ OCStackResult ret = GetDoxmDeviceID( &deviceId);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ memcpy(&gPconf->deviceID, &deviceId, sizeof(OicUuid_t));
+ }
+ VERIFY_NON_NULL(TAG, gPconf, ERROR);
+
+ // Instantiate 'oic.sec.pconf'
+ ret = CreatePconfResource();
+
+exit:
+ if (OC_STACK_OK != ret)
+ {
+ DeInitPconfResource();
+ }
+ OICFree(data);
+ return ret;
+}
+
+/**
+ * Perform cleanup for PCONF resources.
+ *
+ * @return
+ * OC_STACK_OK - no error
+ * OC_STACK_ERROR - stack process error
+ *
+ */
+OCStackResult DeInitPconfResource()
+{
+ OCStackResult ret = OCDeleteResource(gPconfHandle);
+ if(gPconf!= &gDefaultPconf)
+ {
+ DeletePconfBinData(gPconf);
+ }
+ gPconf = NULL;
+
+ if(OC_STACK_OK == ret)
+ {
+ return OC_STACK_OK;
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
+}
+
+/**
+ * This method might be used to add a paired device id after direct-pairing process complete.
+ *
+ * @param pdeviceId ID of the paired device.
+ *
+ * @retval OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult AddPairedDevice(OicUuid_t *pdeviceId)
+{
+ if (!gPconf || !pdeviceId)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+
+ OicUuid_t *prevList = gPconf->pddevs;
+ gPconf->pddevs = (OicUuid_t *)OICCalloc(gPconf->pddevLen+1, sizeof(OicUuid_t));
+ if(!gPconf->pddevs)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+ for (size_t i=0; i<gPconf->pddevLen; i++)
+ {
+ memcpy(&gPconf->pddevs[i], &prevList[i], sizeof(OicUuid_t));
+ }
+
+ // add new paired device id
+ memcpy(&gPconf->pddevs[gPconf->pddevLen], pdeviceId, sizeof(OicUuid_t));
+ gPconf->pddevLen++;
+
+ // Update storage
+ if(true != UpdatePersistentStorage(gPconf))
+ {
+ OIC_LOG (ERROR, TAG, "Fail to update pconf resource");
+ return OC_STACK_ERROR;
+ }
+
+ OIC_LOG (ERROR, TAG, "Add paired device success");
+ return OC_STACK_OK;
+}
+
+/**
+ * This method might be used by PolicyEngine to retrieve PDACL for a Subject.
+ *
+ * @param subjectId ID of the subject for which PDACL is required.
+ * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
+ * successive calls for same subjectId.
+ *
+ * @retval reference to @ref OicSecPdAcl_t if PDACL is found, else NULL
+ */
+const OicSecPdAcl_t* GetPdAclData(const OicUuid_t* subjectId, OicSecPdAcl_t **savePtr)
+{
+ OicSecPdAcl_t *pdacl = NULL;
+
+ if ( NULL == subjectId)
+ {
+ return NULL;
+ }
+
+ /*
+ * savePtr MUST point to NULL if this is the 'first' call to retrieve PDACL for
+ * subjectID.
+ */
+ if (NULL == *savePtr)
+ {
+ pdacl = gPconf->pdacls;
+
+ // Find if 'subjectID' is in paired device list.
+ for(size_t i=0; i<gPconf->pddevLen; i++)
+ {
+ if (memcmp(&(gPconf->pddevs[i]), subjectId, sizeof(OicUuid_t)) == 0)
+ {
+ *savePtr = pdacl;
+ return pdacl;
+ }
+ }
+ }
+ else
+ {
+ OicSecPdAcl_t *temp = NULL;
+
+ /*
+ * If this is a 'successive' call, search for location pointed by
+ * savePtr and assign 'begin' to the next PDACL after it in the linked
+ * list and start searching from there.
+ */
+ LL_FOREACH(gPconf->pdacls, temp)
+ {
+ if (temp == *savePtr)
+ {
+ pdacl = temp->next;
+ *savePtr = pdacl;
+ return pdacl;
+ }
+ }
+ }
+
+ // Cleanup in case no PDACL is found
+ *savePtr = NULL;
+ return NULL;
+}
+
+/**
+ * This method return whether device is paired or not.
+ *
+ * @param pdeviceId Target device ID to find in paired list.
+ * @retval ture if device is already paired, else false
+ */
+bool IsPairedDevice(const OicUuid_t* pdeviceId)
+{
+ // Find if 'pdeviceId' is in paired device list.
+ for(size_t i=0; i<gPconf->pddevLen; i++)
+ {
+ if (memcmp(&(gPconf->pddevs[i]), pdeviceId, sizeof(OicUuid_t)) == 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+OCStackResult SetPconfRownerId(const OicUuid_t* newROwner)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ uint8_t *cborPayload = NULL;
+ size_t size = 0;
+ OicUuid_t prevId = {.id={0}};
+
+ if(NULL == newROwner)
+ {
+ ret = OC_STACK_INVALID_PARAM;
+ }
+ if(NULL == gPconf)
+ {
+ ret = OC_STACK_NO_RESOURCE;
+ }
+
+ if(newROwner && gPconf)
+ {
+ memcpy(prevId.id, gPconf->rownerID.id, sizeof(prevId.id));
+ memcpy(gPconf->rownerID.id, newROwner->id, sizeof(newROwner->id));
+
+ ret = PconfToCBORPayload(gPconf, &cborPayload, &size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ ret = UpdateSecureResourceInPS(OIC_JSON_PCONF_NAME, cborPayload, size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ OICFree(cborPayload);
+ }
+
+ return ret;
+
+exit:
+ OICFree(cborPayload);
+ memcpy(gPconf->rownerID.id, prevId.id, sizeof(prevId.id));
+ return ret;
+}
+
+OCStackResult GetPconfRownerId(OicUuid_t *rowneruuid)
+{
+ OCStackResult retVal = OC_STACK_ERROR;
+ if (gPconf)
+ {
+ *rowneruuid = gPconf->rownerID;
+ retVal = OC_STACK_OK;
+ }
+ return retVal;
+}
// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <string.h>
#include "oic_malloc.h"
#include "policyengine.h"
#include "srmutility.h"
#include "doxmresource.h"
#include "iotvticalendar.h"
-#include <string.h>
+#include "pstatresource.h"
+#include "dpairingresource.h"
+#include "pconfresource.h"
+#include "amaclresource.h"
+#include "credresource.h"
#define TAG "SRM-PE"
-/**
- * Return the uint16_t CRUDN permission corresponding to passed CAMethod_t.
- */
uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method)
{
uint16_t perm = 0;
- switch(method)
+ switch (method)
{
case CA_GET:
perm = (uint16_t)PERMISSION_READ;
}
/**
- * @brief Compares two OicUuid_t structs.
+ * Compares two OicUuid_t structs.
+ *
* @return true if the two OicUuid_t structs are equal, else false.
*/
-bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId)
+static bool UuidCmp(OicUuid_t *firstId, OicUuid_t *secondId)
{
// TODO use VERIFY macros to check for null when they are merged.
if(NULL == firstId || NULL == secondId)
{
return false;
}
+ // Check empty uuid string
+ if('\0' == firstId->id[0] || '\0' == secondId->id[0])
+ {
+ return false;
+ }
for(int i = 0; i < UUID_LENGTH; i++)
{
if(firstId->id[i] != secondId->id[i])
return true;
}
-/**
- * Set the state and clear other stateful context vars.
- */
void SetPolicyEngineState(PEContext_t *context, const PEState_t state)
{
- if(NULL == context)
+ if (NULL == context)
{
return;
}
}
/**
- * @brief Compare the request's subject to DevOwner.
+ * Compare the request's subject to DevOwner.
*
- * @return true if context->subjectId == GetDoxmDevOwner(), else false
+ * @return true if context->subjectId == GetDoxmDevOwner(), else false.
*/
-bool IsRequestFromDevOwner(PEContext_t *context)
+static bool IsRequestFromDevOwner(PEContext_t *context)
{
bool retVal = false;
- OicUuid_t owner;
+ OicUuid_t ownerid;
if(NULL == context)
{
- return OC_STACK_ERROR;
+ return retVal;
}
- if(OC_STACK_OK == GetDoxmDevOwnerId(&owner))
+ if(OC_STACK_OK == GetDoxmDevOwnerId(&ownerid))
{
- retVal = UuidCmp(&context->subject, &owner);
+ retVal = UuidCmp(&context->subject, &ownerid);
}
return retVal;
}
+// TODO - remove these function placeholders as they are implemented
+// in the resource entity handler code.
+// Note that because many SVRs do not have a rowner, in those cases we
+// just return "OC_STACK_ERROR" which results in a "false" return by
+// IsRequestFromResourceOwner().
+// As these SVRs are revised to have a rowner, these functions should be
+// replaced (see pstatresource.c for example of GetPstatRownerId).
+
+OCStackResult GetCrlRownerId(OicUuid_t *rowner)
+{
+ rowner = NULL;
+ return OC_STACK_ERROR;
+}
+
+OCStackResult GetSaclRownerId(OicUuid_t *rowner)
+{
+ rowner = NULL;
+ return OC_STACK_ERROR;
+}
+
+OCStackResult GetSvcRownerId(OicUuid_t *rowner)
+{
+ rowner = NULL;
+ return OC_STACK_ERROR;
+}
+
+static GetSvrRownerId_t GetSvrRownerId[OIC_SEC_SVR_TYPE_COUNT] = {
+ GetAclRownerId,
+ GetAmaclRownerId,
+ GetCredRownerId,
+ GetCrlRownerId,
+ GetDoxmRownerId,
+ GetDpairingRownerId,
+ GetPconfRownerId,
+ GetPstatRownerId,
+ GetSaclRownerId,
+ GetSvcRownerId
+};
+
+/**
+ * Compare the request's subject to resource.ROwner.
+ *
+ * @return true if context->subjectId equals SVR rowner id, else return false
+ */
+bool IsRequestFromResourceOwner(PEContext_t *context)
+{
+ bool retVal = false;
+ OicUuid_t resourceOwner;
+
+ if(NULL == context)
+ {
+ return false;
+ }
+
+ if((OIC_R_ACL_TYPE <= context->resourceType) && \
+ (OIC_SEC_SVR_TYPE_COUNT > context->resourceType))
+ {
+ if(OC_STACK_OK == GetSvrRownerId[(int)context->resourceType](&resourceOwner))
+ {
+ retVal = UuidCmp(&context->subject, &resourceOwner);
+ }
+ }
+
+ if(true == retVal)
+ {
+ OIC_LOG(INFO, TAG, "PE.IsRequestFromResourceOwner(): returning true");
+ }
+ else
+ {
+ OIC_LOG(INFO, TAG, "PE.IsRequestFromResourceOwner(): returning false");
+ }
+
+ return retVal;
+}
inline static bool IsRequestSubjectEmpty(PEContext_t *context)
{
true : false;
}
-
/**
* Bitwise check to see if 'permission' contains 'request'.
- * @param permission The allowed CRUDN permission.
- * @param request The CRUDN permission being requested.
+ *
+ * @param permission is the allowed CRUDN permission.
+ * @param request is the CRUDN permission being requested.
+ *
* @return true if 'permission' bits include all 'request' bits.
*/
static inline bool IsPermissionAllowingRequest(const uint16_t permission,
const uint16_t request)
{
- if(request == (request & permission))
+ if (request == (request & permission))
{
return true;
}
/**
* Compare the passed subject to the wildcard (aka anonymous) subjectId.
+ *
* @return true if 'subject' is the wildcard, false if it is not.
*/
static inline bool IsWildCardSubject(OicUuid_t *subject)
/**
* Copy the subject, resource and permission into the context fields.
*/
-void CopyParamsToContext(
- PEContext_t *context,
- const OicUuid_t *subjectId,
- const char *resource,
- const uint16_t requestedPermission)
+static void CopyParamsToContext(PEContext_t *context,
+ const OicUuid_t *subjectId,
+ const char *resource,
+ const uint16_t requestedPermission)
{
size_t length = 0;
- if(NULL == context || NULL == subjectId || NULL == resource)
+ if (NULL == context || NULL == subjectId || NULL == resource)
{
return;
}
// Copy the resource string into context.
length = strlen(resource) + 1;
- if(0 < length)
+ if (0 < length)
{
strncpy(context->resource, resource, length);
context->resource[length - 1] = '\0';
context->permission = requestedPermission;
}
-
/**
* Check whether 'resource' is getting accessed within the valid time period.
- * @param acl The ACL to check.
- * @return
- * true if access is within valid time period or if the period or recurrence is not present.
- * false if period and recurrence present and the access is not within valid time period.
+ *
+ * @param acl is the ACL to check.
+ *
+ * @return true if access is within valid time period or if the period or recurrence is not present.
+ * false if period and recurrence present and the access is not within valid time period.
*/
static bool IsAccessWithinValidTime(const OicSecAcl_t *acl)
{
#ifndef WITH_ARDUINO //Period & Recurrence not supported on Arduino due
//lack of absolute time
- if(NULL== acl || NULL == acl->periods || 0 == acl->prdRecrLen)
+ if (NULL== acl || NULL == acl->periods || 0 == acl->prdRecrLen)
{
return true;
}
//periods & recurrences rules are paired.
- if(NULL == acl->recurrences)
+ if (NULL == acl->recurrences)
{
return false;
}
- for(size_t i = 0; i < acl->prdRecrLen; i++)
+ for (size_t i = 0; i < acl->prdRecrLen; i++)
{
- if(IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(acl->periods[i],
+ if (IOTVTICAL_VALID_ACCESS == IsRequestWithinValidTime(acl->periods[i],
acl->recurrences[i]))
{
OIC_LOG(INFO, TAG, "Access request is in allowed time period");
/**
* Check whether 'resource' is in the passed ACL.
- * @param resource The resource to search for.
- * @param acl The ACL to check.
+ *
+ * @param resource is the resource being searched.
+ * @param acl is the ACL to check.
+ *
* @return true if 'resource' found, otherwise false.
*/
- bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl)
+ static bool IsResourceInAcl(const char *resource, const OicSecAcl_t *acl)
{
- if(NULL== acl || NULL == resource)
+ if (NULL== acl || NULL == resource)
{
return false;
}
- for(size_t n = 0; n < acl->resourcesLen; n++)
+ for (size_t n = 0; n < acl->resourcesLen; n++)
{
- if(0 == strcmp(resource, acl->resources[n]) || // TODO null terms?
- 0 == strcmp(WILDCARD_RESOURCE_URI, acl->resources[n]))
+ if (0 == strcmp(resource, acl->resources[n]) || // TODO null terms?
+ 0 == strcmp(WILDCARD_RESOURCE_URI, acl->resources[n]))
{
return true;
}
* Search each ACL for requested resource.
* If resource found, check for context->permission and period validity.
* If the ACL is not found locally and AMACL for the resource is found
- * then sends the request to AMS service for the ACL
+ * then sends the request to AMS service for the ACL.
* Set context->retVal to result from first ACL found which contains
* correct subject AND resource.
- *
- * @retval void
*/
-void ProcessAccessRequest(PEContext_t *context)
+static void ProcessAccessRequest(PEContext_t *context)
{
OIC_LOG(DEBUG, TAG, "Entering ProcessAccessRequest()");
- if(NULL != context)
+ if (NULL != context)
{
const OicSecAcl_t *currentAcl = NULL;
OicSecAcl_t *savePtr = NULL;
OIC_LOG_V(DEBUG, TAG, "%s: getting ACL..." ,__func__);
currentAcl = GetACLResourceData(&context->subject, &savePtr);
- if(NULL != currentAcl)
+ if (NULL != currentAcl)
{
// Found the subject, so how about resource?
OIC_LOG_V(DEBUG, TAG, "%s:found ACL matching subject" ,__func__);
// Subject was found, so err changes to Rsrc not found for now.
context->retVal = ACCESS_DENIED_RESOURCE_NOT_FOUND;
OIC_LOG_V(DEBUG, TAG, "%s:Searching for resource..." ,__func__);
- if(IsResourceInAcl(context->resource, currentAcl))
+ if (IsResourceInAcl(context->resource, currentAcl))
{
OIC_LOG_V(INFO, TAG, "%s:found matching resource in ACL" ,__func__);
context->matchingAclFound = true;
// Found the resource, so it's down to valid period & permission.
context->retVal = ACCESS_DENIED_INVALID_PERIOD;
- if(IsAccessWithinValidTime(currentAcl))
+ if (IsAccessWithinValidTime(currentAcl))
{
context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION;
- if(IsPermissionAllowingRequest(currentAcl->permission, context->permission))
+ if (IsPermissionAllowingRequest(currentAcl->permission, context->permission))
{
context->retVal = ACCESS_GRANTED;
}
{
OIC_LOG_V(INFO, TAG, "%s:no ACL found matching subject for resource %s",__func__, context->resource);
}
- }
- while((NULL != currentAcl) && (false == context->matchingAclFound));
+ } while ((NULL != currentAcl) && (false == context->matchingAclFound));
- if(IsAccessGranted(context->retVal))
+ if (IsAccessGranted(context->retVal))
{
OIC_LOG_V(INFO, TAG, "%s:Leaving ProcessAccessRequest(ACCESS_GRANTED)", __func__);
}
}
}
-/**
- * Check whether a request should be allowed.
- * @param context Pointer to (Initialized) Policy Engine context to use.
- * @param subjectId Pointer to Id of the requesting entity.
- * @param resource Pointer to URI of Resource being requested.
- * @param permission Requested permission.
- * @return ACCESS_GRANTED if request should go through,
- * otherwise some flavor of ACCESS_DENIED
- */
-SRMAccessResponse_t CheckPermission(
- PEContext_t *context,
- const OicUuid_t *subjectId,
- const char *resource,
- const uint16_t requestedPermission)
+SRMAccessResponse_t CheckPermission(PEContext_t *context,
+ const OicUuid_t *subjectId,
+ const char *resource,
+ const uint16_t requestedPermission)
{
SRMAccessResponse_t retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR;
// Each state machine context can only be processing one request at a time.
// Therefore if the context is not in AWAITING_REQUEST or AWAITING_AMS_RESPONSE
// state, return error. Otherwise, change to BUSY state and begin processing request.
- if(AWAITING_REQUEST == context->state || AWAITING_AMS_RESPONSE == context->state)
+ if (AWAITING_REQUEST == context->state || AWAITING_AMS_RESPONSE == context->state)
{
- if(AWAITING_REQUEST == context->state)
+ if (AWAITING_REQUEST == context->state)
{
SetPolicyEngineState(context, BUSY);
CopyParamsToContext(context, subjectId, resource, requestedPermission);
// Before doing any processing, check if request coming
// from DevOwner and if so, always GRANT.
- if(IsRequestFromDevOwner(context))
+ if (IsRequestFromDevOwner(context))
+ {
+ context->retVal = ACCESS_GRANTED;
+ }
+ // Then check if request is for a SVR and coming from rowner
+ else if (IsRequestFromResourceOwner(context))
{
context->retVal = ACCESS_GRANTED;
}
+ // Else request is a "normal" request that must be tested against ACL
else
{
OicUuid_t saveSubject = {.id={}};
ProcessAccessRequest(context);
// If matching ACL not found, and subject != wildcard, try wildcard.
- if((false == context->matchingAclFound) && \
+ if ((false == context->matchingAclFound) && \
(false == IsWildCardSubject(&context->subject)))
{
//Saving subject for Amacl check
}
//No local ACE found for the request so checking Amacl resource
- if(ACCESS_GRANTED != context->retVal)
+ if (ACCESS_GRANTED != context->retVal)
{
//If subject is not empty then restore the original subject
//else keep the subject to WILDCARD_SUBJECT_ID
// Capture retVal before resetting state for next request.
retVal = context->retVal;
- if(!context->amsProcessing)
+ if (!context->amsProcessing)
{
OIC_LOG(INFO, TAG, "Resetting PE context and PE State to AWAITING_REQUEST");
SetPolicyEngineState(context, AWAITING_REQUEST);
return retVal;
}
-/**
- * Initialize the Policy Engine. Call this before calling CheckPermission().
- * @param context Pointer to Policy Engine context to initialize.
- * @return OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult InitPolicyEngine(PEContext_t *context)
{
if(NULL == context)
return OC_STACK_OK;
}
-/**
- * De-Initialize the Policy Engine. Call this before exiting to allow Policy
- * Engine to do cleanup on context.
- * @param context Pointer to Policy Engine context to de-initialize.
- * @return none
- */
void DeInitPolicyEngine(PEContext_t *context)
{
if(NULL != context)
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include "ocstack.h"
+#ifdef WITH_ARDUINO
+#define __STDC_LIMIT_MACROS
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cainterface.h"
#include "logger.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
+#include "ocstack.h"
#include "oic_malloc.h"
-#include "cJSON.h"
-#include "cainterface.h"
-#include "secureresourcemanager.h"
+#include "payload_logging.h"
#include "resourcemanager.h"
+#include "secureresourcemanager.h"
#include "srmresourcestrings.h"
#include "srmutility.h"
-#include <stdlib.h>
-#include <string.h>
#define TAG "SRM-PSI"
const size_t DB_FILE_SIZE_BLOCK = 1023;
/**
- * Gets the Secure Virtual Database size.
+ * Gets the Secure Virtual Database size
*
- * @param ps pointer of OCPersistentStorage for the SVR name ("acl", "cred", "pstat" etc).
+ * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
*
- * @retval total size of the SVR database.
+ * @return size_t - total size of the SVR database
*/
-size_t GetSVRDatabaseSize(OCPersistentStorage* ps)
+static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
{
- size_t size = 0;
if (!ps)
{
- return size;
+ return 0;
}
- size_t bytesRead = 0;
- char buffer[DB_FILE_SIZE_BLOCK];
- FILE* fp = ps->open(SVR_DB_FILE_NAME, "r");
+ size_t size = 0;
+ char buffer[DB_FILE_SIZE_BLOCK]; // can not initialize with declaration
+ // but maybe not needed to initialize
+ FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
if (fp)
{
+ size_t bytesRead = 0;
do
{
bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
size += bytesRead;
- } while (bytesRead > 0);
+ } while (bytesRead);
ps->close(fp);
}
return size;
}
/**
- * Reads the Secure Virtual Database from PS into dynamically allocated
- * memory buffer.
+ * Gets the Secure Virtual Database from the Persistent Storage
*
- * @note Caller of this method MUST use OICFree() method to release memory
- * referenced by return value.
+ * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
+ * @param data - pointer of the returned Secure Virtual Resource(s)
+ * @param size - pointer of the returned size of Secure Virtual Resource(s)
*
- * @retval reference to memory buffer containing SVR database.
+ * @return OCStackResult - result of getting Secure Virtual Resource(s)
*/
-char * GetSVRDatabase()
+OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
{
- char * jsonStr = NULL;
- FILE * fp = NULL;
- OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
- int size = GetSVRDatabaseSize(ps);
- if (0 == size)
+ OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS IN");
+ if (!data || *data || !size)
{
- OIC_LOG (ERROR, TAG, "FindSVRDatabaseSize failed");
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
- if (ps && ps->open)
+ FILE *fp = NULL;
+ uint8_t *fsData = NULL;
+ size_t fileSize = 0;
+ OCStackResult ret = OC_STACK_ERROR;
+
+ OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
+ VERIFY_NON_NULL(TAG, ps, ERROR);
+
+ fileSize = GetSVRDatabaseSize(ps);
+ OIC_LOG_V(DEBUG, TAG, "File Read Size: %zu", fileSize);
+ if (fileSize)
{
- // Open default SRM database file. An app could change the path for its server.
- fp = ps->open(SVR_DB_FILE_NAME, "r");
- if (fp)
- {
- jsonStr = (char*)OICMalloc(size + 1);
- VERIFY_NON_NULL(TAG, jsonStr, FATAL);
- size_t bytesRead = ps->read(jsonStr, 1, size, fp);
- jsonStr[bytesRead] = '\0';
-
- OIC_LOG_V(DEBUG, TAG, "Read %zu bytes from SVR database file", bytesRead);
- ps->close(fp);
- fp = NULL;
- }
- else
+ fsData = (uint8_t *) OICCalloc(1, fileSize);
+ VERIFY_NON_NULL(TAG, fsData, ERROR);
+
+ fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
+ VERIFY_NON_NULL(TAG, fp, ERROR);
+ if (ps->read(fsData, 1, fileSize, fp) == fileSize)
{
- OIC_LOG (ERROR, TAG, "Unable to open SVR database file!!");
+ if (rsrcName)
+ {
+ CborParser parser; // will be initialized in |cbor_parser_init|
+ CborValue cbor; // will be initialized in |cbor_parser_init|
+ cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
+ CborValue cborValue = {0};
+ CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
+ VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
+ ret = OC_STACK_OK;
+ }
+ // in case of |else (...)|, svr_data not found
+ }
+ // return everything in case rsrcName is NULL
+ else
+ {
+ *size = fileSize;
+ *data = (uint8_t *) OICCalloc(1, fileSize);
+ VERIFY_NON_NULL(TAG, *data, ERROR);
+ memcpy(*data, fsData, fileSize);
+ ret = OC_STACK_OK;
+ }
}
}
+ OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS OUT");
exit:
- if (ps && fp)
+ if (fp)
{
ps->close(fp);
}
- return jsonStr;
+ OICFree(fsData);
+ return ret;
}
-
/**
- * This method is used by a entity handlers of SVR's to update
- * SVR database.
+ * Updates the Secure Virtual Resource(s) into the Persistent Storage.
+ * This function stores cbor-payload of each resource by appending resource name,
+ * and empty payload implies deleting the value
*
- * @param rsrcName string denoting the SVR name ("acl", "cred", "pstat" etc).
- * @param jsonObj JSON object containing the SVR contents.
+ * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
+ * @param psPayload - pointer of the updated Secure Virtual Resource(s)
+ * @param psSize - the updated size of Secure Virtual Resource(s)
*
- * @retval OC_STACK_OK for Success, otherwise some error value
+ * @return OCStackResult - result of updating Secure Virtual Resource(s)
*/
-OCStackResult UpdateSVRDatabase(const char* rsrcName, cJSON* jsonObj)
+OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
{
- OCStackResult ret = OC_STACK_ERROR;
- cJSON *jsonSVRDb = NULL;
- OCPersistentStorage* ps = NULL;
-
- // Read SVR database from PS
- char* jsonSVRDbStr = GetSVRDatabase();
- VERIFY_NON_NULL(TAG,jsonSVRDbStr, ERROR);
+ OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS IN");
+ if (!rsrcName)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
- // Use cJSON_Parse to parse the existing SVR database
- jsonSVRDb = cJSON_Parse(jsonSVRDbStr);
- VERIFY_NON_NULL(TAG,jsonSVRDb, ERROR);
+ size_t dbSize = 0;
+ size_t outSize = 0;
+ uint8_t *dbData = NULL;
+ uint8_t *outPayload = NULL;
- OICFree(jsonSVRDbStr);
- jsonSVRDbStr = NULL;
+ uint8_t *aclCbor = NULL;
+ uint8_t *pstatCbor = NULL;
+ uint8_t *doxmCbor = NULL;
+ uint8_t *amaclCbor = NULL;
+ uint8_t *svcCbor = NULL;
+ uint8_t *credCbor = NULL;
+ uint8_t *pconfCbor = NULL;
- //If Cred resource gets updated with empty list then delete the Cred
- //object from database.
- if(NULL == jsonObj && (0 == strcmp(rsrcName, OIC_JSON_CRED_NAME)))
+ int64_t cborEncoderResult = CborNoError;
+ OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
+ if (dbData && dbSize)
{
- cJSON_DeleteItemFromObject(jsonSVRDb, rsrcName);
- }
- else if (jsonObj->child )
- {
- // Create a duplicate of the JSON object which was passed.
- cJSON* jsonDuplicateObj = cJSON_Duplicate(jsonObj, 1);
- VERIFY_NON_NULL(TAG,jsonDuplicateObj, ERROR);
-
- cJSON* jsonObj = cJSON_GetObjectItem(jsonSVRDb, rsrcName);
-
- /*
- ACL, PStat & Doxm resources at least have default entries in the database but
- Cred resource may have no entries. The first cred resource entry (for provisioning tool)
- is created when the device is owned by provisioning tool and it's ownerpsk is generated.*/
- if((strcmp(rsrcName, OIC_JSON_CRED_NAME) == 0 ||
- strcmp(rsrcName, OIC_JSON_CRL_NAME) == 0 ||
- strcmp(rsrcName, OIC_JSON_PCONF_NAME) == 0 ||
- strcmp(rsrcName, OIC_JSON_DPAIRING_NAME) == 0) && (!jsonObj))
+ size_t aclCborLen = 0;
+ size_t pstatCborLen = 0;
+ size_t doxmCborLen = 0;
+ size_t amaclCborLen = 0;
+ size_t svcCborLen = 0;
+ size_t credCborLen = 0;
+ size_t pconfCborLen = 0;
+
+ // Gets each secure virtual resource from persistent storage
+ // this local scoping intended, for destroying large cbor instances after use
{
- // Add the fist cred object in existing SVR database json
- cJSON_AddItemToObject(jsonSVRDb, rsrcName, jsonDuplicateObj->child);
+ CborParser parser; // will be initialized in |cbor_parser_init|
+ CborValue cbor; // will be initialized in |cbor_parser_init|
+ cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
+ CborValue curVal = {0};
+ CborError cborFindResult = CborNoError;
+
+ cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
+ }
+ cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&curVal, &pstatCbor, &pstatCborLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
+ }
+ cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_DOXM_NAME, &curVal);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&curVal, &doxmCbor, &doxmCborLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding DOXM Name Value.");
+ }
+ cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_AMACL_NAME, &curVal);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
+ }
+ cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_SVC_NAME, &curVal);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&curVal, &svcCbor, &svcCborLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SVC Name Value.");
+ }
+ cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
+ }
+ cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PCONF_NAME, &curVal);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&curVal, &pconfCbor, &pconfCborLen, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PCONF Name Value.");
+ }
}
- else
+
+ // Updates the added |psPayload| with the existing secure virtual resource(s)
+ // this local scoping intended, for destroying large cbor instances after use
{
- VERIFY_NON_NULL(TAG,jsonObj, ERROR);
+ size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
+ + svcCborLen + credCborLen + pconfCborLen + psSize + 255;
+ // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
+
+ outPayload = (uint8_t *) OICCalloc(1, size);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ CborEncoder encoder; // will be initialized in |cbor_parser_init|
+ cbor_encoder_init(&encoder, outPayload, size, 0);
+ CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
+ cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
+
+ if (psPayload && psSize)
+ {
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
+ }
+ if (strcmp(OIC_JSON_ACL_NAME, rsrcName) && aclCborLen)
+ {
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
+ }
+ if (strcmp(OIC_JSON_PSTAT_NAME, rsrcName) && pstatCborLen)
+ {
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
+ }
+ if (strcmp(OIC_JSON_DOXM_NAME, rsrcName) && doxmCborLen)
+ {
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Name.");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, doxmCbor, doxmCborLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Doxm Value.");
+ }
+ if (strcmp(OIC_JSON_AMACL_NAME, rsrcName) && amaclCborLen)
+ {
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Name.");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
+ }
+ if (strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen)
+ {
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
+ }
+ if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
+ {
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Name.");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Cred Value.");
+ }
+ if (strcmp(OIC_JSON_PCONF_NAME, rsrcName) && pconfCborLen)
+ {
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PCONF_NAME, strlen(OIC_JSON_PCONF_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Name.");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pconfCbor, pconfCborLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pconf Value.");
+ }
- // Replace the modified json object in existing SVR database json
- cJSON_ReplaceItemInObject(jsonSVRDb, rsrcName, jsonDuplicateObj->child);
+ cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
+ outSize = encoder.ptr - outPayload;
}
}
+ else if (psPayload && psSize)
+ {
+ size_t size = psSize + 255;
+ // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
- // Generate string representation of updated SVR database json object
- jsonSVRDbStr = cJSON_PrintUnformatted(jsonSVRDb);
- VERIFY_NON_NULL(TAG,jsonSVRDbStr, ERROR);
+ outPayload = (uint8_t *) OICCalloc(1, size);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ CborEncoder encoder; // will be initialized in |cbor_parser_init|
+ cbor_encoder_init(&encoder, outPayload, size, 0);
+ CborEncoder secRsrc; // will be initialized in |cbor_encoder_create_map|
+ cborEncoderResult |= cbor_encoder_create_map(&encoder, &secRsrc, CborIndefiniteLength);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PS Map.");
- // Update the persistent storage with new SVR database
- ps = SRMGetPersistentStorageHandler();
- if (ps && ps->open)
+ cborEncoderResult |= cbor_encode_text_string(&secRsrc, rsrcName, strlen(rsrcName));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value Tag");
+ cborEncoderResult |= cbor_encode_byte_string(&secRsrc, psPayload, psSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Value.");
+
+ cborEncoderResult |= cbor_encoder_close_container(&encoder, &secRsrc);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Array.");
+ outSize = encoder.ptr - outPayload;
+ }
+
+ if (outPayload && outSize)
{
- FILE* fp = ps->open(SVR_DB_FILE_NAME, "w");
- if (fp)
+ OIC_LOG_V(DEBUG, TAG, "Writting in the file: %zu", outSize);
+ OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
+ if (ps)
{
- size_t bytesWritten = ps->write(jsonSVRDbStr, 1, strlen(jsonSVRDbStr), fp);
- if (bytesWritten == strlen(jsonSVRDbStr))
+ FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
+ if (fp)
{
- ret = OC_STACK_OK;
+ size_t numberItems = ps->write(outPayload, 1, outSize, fp);
+ if (outSize == numberItems)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
+ ret = OC_STACK_OK;
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
+ }
+ ps->close(fp);
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "File open failed.");
}
- OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", bytesWritten);
- ps->close(fp);
- fp = NULL;
- }
- else
- {
- OIC_LOG (ERROR, TAG, "Unable to open SVR database file!! ");
}
}
-exit:
- OICFree(jsonSVRDbStr);
- cJSON_Delete(jsonSVRDb);
+ OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS OUT");
+exit:
+ OICFree(dbData);
+ OICFree(outPayload);
+ OICFree(aclCbor);
+ OICFree(pstatCbor);
+ OICFree(doxmCbor);
+ OICFree(amaclCbor);
+ OICFree(svcCbor);
+ OICFree(credCbor);
+ OICFree(pconfCbor);
return ret;
}
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdlib.h>
+#include <string.h>
+
#include "ocstack.h"
-#include "logger.h"
#include "oic_malloc.h"
-#include "cJSON.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
#include "resourcemanager.h"
#include "pstatresource.h"
#include "doxmresource.h"
#include "psinterface.h"
-#include "utlist.h"
-#include "base64.h"
#include "srmresourcestrings.h"
#include "srmutility.h"
-#include <stdlib.h>
-#include <string.h>
#define TAG "SRM-PSTAT"
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching below max cbor size. */
+static const uint16_t CBOR_SIZE = 512;
+
+// Max cbor size payload.
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+// PSTAT Map size - Number of mandatory items
+static const uint8_t PSTAT_MAP_SIZE = 7;
+
static OicSecDpom_t gSm = SINGLE_SERVICE_CLIENT_DRIVEN;
static OicSecPstat_t gDefaultPstat =
{
- false, // bool isOwned
- (OicSecDpm_t)(TAKE_OWNER | BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
+ false, // bool isop
+ (OicSecDpm_t)(BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
PROVISION_CREDENTIALS | PROVISION_ACLS), // OicSecDpm_t cm
(OicSecDpm_t)(TAKE_OWNER | BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
PROVISION_CREDENTIALS | PROVISION_ACLS), // OicSecDpm_t tm
1, // the number of elts in Sms
&gSm, // OicSecDpom_t *sm
0, // uint16_t commitHash
+ {.id = {0}}, // OicUuid_t rownerID
};
static OicSecPstat_t *gPstat = NULL;
}
}
-char * BinToPstatJSON(const OicSecPstat_t * pstat)
+OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload, size_t *size)
{
- if(NULL == pstat)
+ if (NULL == pstat || NULL == payload || NULL != *payload || NULL == size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
- cJSON *jsonPstat = NULL;
- char *jsonStr = NULL;
- cJSON *jsonSmArray = NULL;
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*) 0)->id)) + 1] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
-
- cJSON *jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, INFO);
-
- cJSON_AddItemToObject(jsonRoot, OIC_JSON_PSTAT_NAME, jsonPstat=cJSON_CreateObject());
- cJSON_AddBoolToObject(jsonPstat, OIC_JSON_ISOP_NAME, pstat->isOp);
+ size_t cborLen = *size;
+ if (0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
+ }
- b64Ret = b64Encode(pstat->deviceID.id,
- sizeof(pstat->deviceID.id), base64Buff, sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+ *payload = NULL;
+ *size = 0;
- cJSON_AddStringToObject(jsonPstat, OIC_JSON_DEVICE_ID_NAME, base64Buff);
- cJSON_AddNumberToObject(jsonPstat, OIC_JSON_COMMIT_HASH_NAME, pstat->commitHash);
- cJSON_AddNumberToObject(jsonPstat, OIC_JSON_CM_NAME, (int)pstat->cm);
- cJSON_AddNumberToObject(jsonPstat, OIC_JSON_TM_NAME, (int)pstat->tm);
- cJSON_AddNumberToObject(jsonPstat, OIC_JSON_OM_NAME, (int)pstat->om);
+ OCStackResult ret = OC_STACK_ERROR;
- cJSON_AddItemToObject(jsonPstat, OIC_JSON_SM_NAME, jsonSmArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonSmArray, INFO);
- for (size_t i = 0; i < pstat->smLen; i++)
+ CborEncoder encoder;
+ CborEncoder pstatMap;
+ char* strUuid = NULL;
+
+ int64_t cborEncoderResult = CborNoError;
+
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+ cborEncoderResult = cbor_encoder_create_map(&encoder, &pstatMap, PSTAT_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pstat Map.");
+
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_ISOP_NAME,
+ strlen(OIC_JSON_ISOP_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ISOP Name Tag.");
+ cborEncoderResult = cbor_encode_boolean(&pstatMap, pstat->isOp);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ISOP Name Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_DEVICE_ID_NAME,
+ strlen(OIC_JSON_DEVICE_ID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
+ ret = ConvertUuidToStr(&pstat->deviceID, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
+
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_CM_NAME,
+ strlen(OIC_JSON_CM_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CM Name Tag.");
+ cborEncoderResult = cbor_encode_int(&pstatMap, pstat->cm);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CM Name Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_TM_NAME,
+ strlen(OIC_JSON_TM_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding TM Name Tag.");
+ cborEncoderResult = cbor_encode_int(&pstatMap, pstat->tm);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding TM Name Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_OM_NAME,
+ strlen(OIC_JSON_OM_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OM Name Tag.");
+ cborEncoderResult = cbor_encode_int(&pstatMap, pstat->om);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OM Name Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_SM_NAME,
+ strlen(OIC_JSON_SM_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SM Name Tag.");
+ cborEncoderResult = cbor_encode_int(&pstatMap, pstat->sm[0]);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SM Name Value.");
+
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_ROWNERID_NAME,
+ strlen(OIC_JSON_ROWNERID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Tag.");
+ ret = ConvertUuidToStr(&pstat->rownerID, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&pstatMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
+
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &pstatMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Closing PSTAT Map.");
+
+ if (CborNoError == cborEncoderResult)
{
- cJSON_AddItemToArray(jsonSmArray, cJSON_CreateNumber((int )pstat->sm[i]));
+ *size = encoder.ptr - outPayload;
+ *payload = outPayload;
+ ret = OC_STACK_OK;
}
- jsonStr = cJSON_Print(jsonRoot);
-
exit:
- if (jsonRoot)
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
{
- cJSON_Delete(jsonRoot);
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = PstatToCBORPayload(pstat, payload, &cborLen);
+ if (OC_STACK_OK == ret)
+ {
+ *size = cborLen;
+ }
}
- return jsonStr;
+
+ if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *payload = NULL;
+ *size = 0;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
}
-OicSecPstat_t * JSONToPstatBin(const char * jsonStr)
+OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t size,
+ OicSecPstat_t **secPstat)
{
- if(NULL == jsonStr)
+ if (NULL == cborPayload || NULL == secPstat || NULL != *secPstat || 0 == size)
{
- return NULL;
+ return OC_STACK_INVALID_PARAM;
}
OCStackResult ret = OC_STACK_ERROR;
+ *secPstat = NULL;
+
+ CborValue pstatCbor;
+ CborParser parser;
+ CborError cborFindResult = CborNoError;
+ char *strUuid = NULL;
+ size_t len = 0;
+
+ cbor_parser_init(cborPayload, size, 0, &parser, &pstatCbor);
+ CborValue pstatMap = { .parser = NULL };
+
OicSecPstat_t *pstat = NULL;
- cJSON *jsonPstat = NULL;
- cJSON *jsonObj = NULL;
-
- unsigned char base64Buff[sizeof(((OicUuid_t*) 0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
-
- cJSON *jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, INFO);
-
- jsonPstat = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME);
- VERIFY_NON_NULL(TAG, jsonPstat, INFO);
-
- pstat = (OicSecPstat_t*)OICCalloc(1, sizeof(OicSecPstat_t));
- VERIFY_NON_NULL(TAG, pstat, INFO);
- jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_ISOP_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type) , ERROR);
- pstat->isOp = jsonObj->valueint;
-
- jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_DEVICE_ID_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(pstat->deviceID.id)), ERROR);
- memcpy(pstat->deviceID.id, base64Buff, outLen);
-
- jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_COMMIT_HASH_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- pstat->commitHash = jsonObj->valueint;
-
- jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_CM_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- pstat->cm = (OicSecDpm_t)jsonObj->valueint;
-
- jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- pstat->om = (OicSecDpom_t)jsonObj->valueint;
-
- jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_SM_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- if (cJSON_Array == jsonObj->type)
- {
- pstat->smLen = (size_t)cJSON_GetArraySize(jsonObj);
- size_t idxx = 0;
- VERIFY_SUCCESS(TAG, pstat->smLen != 0, ERROR);
+ cborFindResult = cbor_value_enter_container(&pstatCbor, &pstatMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Map.");
+
+ pstat = (OicSecPstat_t *)OICCalloc(1, sizeof(OicSecPstat_t));
+ VERIFY_NON_NULL(TAG, pstat, ERROR);
+
+ cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_ISOP_NAME, &pstatMap);
+ if (CborNoError == cborFindResult && cbor_value_is_boolean(&pstatMap))
+ {
+ cborFindResult = cbor_value_get_boolean(&pstatMap, &pstat->isOp);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding isOp Value.");
+ }
+
+ cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_DEVICE_ID_NAME, &pstatMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&pstatMap))
+ {
+ cborFindResult = cbor_value_dup_text_string(&pstatMap, &strUuid , &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
+ ret = ConvertStrToUuid(strUuid , &pstat->deviceID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ OICFree(strUuid );
+ strUuid = NULL;
+ }
+
+ cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_CM_NAME, &pstatMap);
+ if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap))
+ {
+ cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->cm);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CM.");
+ }
+
+ cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_TM_NAME, &pstatMap);
+ if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap))
+ {
+ cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->tm);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding TM.");
+ }
+
+ cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_OM_NAME, &pstatMap);
+ if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap))
+ {
+ cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->om);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OM.");
+ }
+
+ cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_SM_NAME, &pstatMap);
+ if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap))
+ {
+ pstat->smLen = 1;
pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
- VERIFY_NON_NULL(TAG, pstat->sm, ERROR);
- do
- {
- cJSON *jsonSm = cJSON_GetArrayItem(jsonObj, idxx);
- VERIFY_NON_NULL(TAG, jsonSm, ERROR);
- pstat->sm[idxx] = (OicSecDpom_t)jsonSm->valueint;
- }while ( ++idxx < pstat->smLen);
+ cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->sm[0]);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM.");
+
+ }
+
+ cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_ROWNERID_NAME, &pstatMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&pstatMap))
+ {
+ cborFindResult = cbor_value_dup_text_string(&pstatMap, &strUuid , &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ROwner Id Value.");
+ ret = ConvertStrToUuid(strUuid , &pstat->rownerID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ OICFree(strUuid );
+ strUuid = NULL;
}
+
+ *secPstat = pstat;
ret = OC_STACK_OK;
exit:
- cJSON_Delete(jsonRoot);
- if (OC_STACK_OK != ret)
+ if (CborNoError != cborFindResult)
{
- OIC_LOG (ERROR, TAG, "JSONToPstatBin failed");
+ OIC_LOG(ERROR, TAG, "CBORPayloadToPstat failed");
DeletePstatBinData(pstat);
pstat = NULL;
+ *secPstat = NULL;
+ ret = OC_STACK_ERROR;
}
- return pstat;
+
+ return ret;
}
/**
* Function to update persistent storage
*/
-static bool UpdatePersistentStorage(OicSecPstat_t * pstat)
+static bool UpdatePersistentStorage(OicSecPstat_t *pstat)
{
bool bRet = false;
- if (pstat)
+ size_t size = 0;
+ uint8_t *cborPayload = NULL;
+ OCStackResult ret = PstatToCBORPayload(pstat, &cborPayload, &size);
+ if (OC_STACK_OK == ret)
{
- // Convert pstat data into JSON for update to persistent storage
- char *jsonStr = BinToPstatJSON(pstat);
- if (jsonStr)
+ if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, cborPayload, size))
{
- cJSON *jsonPstat = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- if (jsonPstat &&
- (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PSTAT_NAME, jsonPstat)))
- {
- bRet = true;
- }
- cJSON_Delete(jsonPstat);
+ bRet = true;
}
+ OICFree(cborPayload);
}
return bRet;
*/
static OCEntityHandlerResult HandlePstatGetRequest (const OCEntityHandlerRequest * ehRequest)
{
- OIC_LOG (INFO, TAG, "HandlePstatGetRequest processing GET request");
- // Convert ACL data into JSON for transmission
- char* jsonStr = BinToPstatJSON(gPstat);
+ OIC_LOG(INFO, TAG, "HandlePstatGetRequest processing GET request");
- // A device should always have a default pstat. Therefore, jsonStr should never be NULL.
- OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
+ // Convert ACL data into CBOR for transmission
+ size_t size = 0;
+ uint8_t *payload = NULL;
+ OCStackResult res = PstatToCBORPayload(gPstat, &payload, &size);
+
+ // A device should always have a default pstat. Therefore, payload should never be NULL.
+ OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
// Send response payload to request originator
- SendSRMResponse(ehRequest, ehRet, jsonStr);
- OICFree(jsonStr);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatGetRequest");
+ }
+ OICFree(payload);
return ehRet;
}
static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest *ehRequest)
{
OCEntityHandlerResult ehRet = OC_EH_ERROR;
- cJSON *postJson = NULL;
- OIC_LOG (INFO, TAG, "HandlePstatPutRequest processing PUT request");
-
- if (ehRequest->resource)
- {
- postJson = cJSON_Parse(((OCSecurityPayload*)ehRequest->payload)->securityData);
- VERIFY_NON_NULL(TAG, postJson, INFO);
- cJSON *jsonPstat = cJSON_GetObjectItem(postJson, OIC_JSON_PSTAT_NAME);
- VERIFY_NON_NULL(TAG, jsonPstat, INFO);
- cJSON *commitHashJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_COMMIT_HASH_NAME);
- uint16_t commitHash = 0;
- if (commitHashJson)
- {
- commitHash = commitHashJson->valueint;
- }
- cJSON *tmJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_TM_NAME);
- if (tmJson && gPstat)
+ OIC_LOG(INFO, TAG, "HandlePstatPutRequest processing PUT request");
+ OicSecPstat_t *pstat = NULL;
+
+ if (ehRequest->payload)
+ {
+ uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
+ VERIFY_NON_NULL(TAG, payload, ERROR);
+
+ OCStackResult ret = CBORPayloadToPstat(payload, size, &pstat);
+ VERIFY_NON_NULL(TAG, pstat, ERROR);
+ if (OC_STACK_OK == ret)
{
- gPstat->tm = (OicSecDpm_t)tmJson->valueint;
- if(0 == tmJson->valueint && gPstat->commitHash == commitHash)
+ if (false == (pstat->cm & TAKE_OWNER) && false == pstat->isOp)
+ {
+ gPstat->cm = pstat->cm;
+ OIC_LOG (INFO, TAG, "State changed to Ready for Provisioning");
+ }
+ else if (false == (pstat->cm & TAKE_OWNER) && true == pstat->isOp)
{
- gPstat->isOp = true;
- gPstat->cm = NORMAL;
- OIC_LOG (INFO, TAG, "CommitHash is valid and isOp is TRUE");
+ gPstat->isOp =pstat->isOp;
+ OIC_LOG (INFO, TAG, "State changed to Ready for Normal Operation");
}
else
{
- OIC_LOG (INFO, TAG, "CommitHash is not valid");
+ OIC_LOG(DEBUG, TAG, "Invalid Device provisionig state");
}
- }
- cJSON *omJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME);
- if (omJson && gPstat)
- {
- /*
- * Check if the operation mode is in the supported provisioning services
- * operation mode list.
- */
- for(size_t i=0; i< gPstat->smLen; i++)
+ if (pstat->om != MULTIPLE_SERVICE_SERVER_DRIVEN && gPstat)
{
- if(gPstat->sm[i] == (unsigned int)omJson->valueint)
+ /*
+ * Check if the operation mode is in the supported provisioning services
+ * operation mode list.
+ */
+ for (size_t i=0; i< gPstat->smLen; i++)
{
- gPstat->om = (OicSecDpom_t)omJson->valueint;
- break;
+ if(gPstat->sm[i] == pstat->om)
+ {
+ gPstat->om = pstat->om;
+ break;
+ }
}
}
- }
- // Convert pstat data into JSON for update to persistent storage
- if(UpdatePersistentStorage(gPstat))
- {
- ehRet = OC_EH_OK;
+ // Convert pstat data into CBOR for update to persistent storage
+ if (UpdatePersistentStorage(gPstat))
+ {
+ ehRet = OC_EH_OK;
+ }
}
}
exit:
}
//Send payload to request originator
- if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))
+ if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
{
+ ehRet = OC_EH_ERROR;
OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest");
}
- cJSON_Delete(postJson);
+ DeletePstatBinData(pstat);
return ehRet;
}
/**
* This internal method is the entity handler for pstat resources.
*/
-OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest,
- void *callbackParam)
+ OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void *callbackParam)
{
(void)callbackParam;
OCEntityHandlerResult ehRet = OC_EH_ERROR;
// This method will handle REST request (GET/POST) for /oic/sec/pstat
if (flag & OC_REQUEST_FLAG)
{
- OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+ OIC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
switch (ehRequest->method)
{
case OC_REST_GET:
break;
default:
ehRet = OC_EH_ERROR;
- SendSRMResponse(ehRequest, ehRet, NULL);
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
break;
}
}
/**
* This internal method is used to create '/oic/sec/pstat' resource.
*/
-OCStackResult CreatePstatResource()
+ OCStackResult CreatePstatResource()
{
- OCStackResult ret;
+ OCStackResult ret = OCCreateResource(&gPstatHandle,
+ OIC_RSRC_TYPE_SEC_PSTAT,
+ OIC_MI_DEF,
+ OIC_RSRC_PSTAT_URI,
+ PstatEntityHandler,
+ NULL,
+ OC_RES_PROP_NONE);
- ret = OCCreateResource(&gPstatHandle,
- OIC_RSRC_TYPE_SEC_PSTAT,
- OIC_MI_DEF,
- OIC_RSRC_PSTAT_URI,
- PstatEntityHandler,
- NULL,
- OC_RES_PROP_NONE);
-
- if (ret != OC_STACK_OK)
+ if (OC_STACK_OK != ret)
{
- OIC_LOG (FATAL, TAG, "Unable to instantiate pstat resource");
+ OIC_LOG(FATAL, TAG, "Unable to instantiate pstat resource");
DeInitPstatResource();
}
return ret;
}
/**
- * Post ACL hander update the commitHash during ACL provisioning.
- */
-void SetCommitHash(uint16_t commitHash)
-{
- gPstat->commitHash = commitHash;
-}
-
-/**
- * Get the default value
- * @retval the gDefaultPstat pointer
+ * Get the default value.
+ *
+ * @return the gDefaultPstat pointer.
*/
static OicSecPstat_t* GetPstatDefault()
{
return &gDefaultPstat;
}
-/**
- * Initialize pstat resource by loading data from persistent storage.
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult InitPstatResource()
{
OCStackResult ret = OC_STACK_ERROR;
// Read Pstat resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
- if (jsonSVRDatabase)
+ uint8_t *data = NULL;
+ size_t size = 0;
+ OicUuid_t emptyUuid = {.id={0}};
+ ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PSTAT_NAME, &data, &size);
+ // If database read failed
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
+ if (data)
{
- // Convert JSON Pstat into binary format
- gPstat = JSONToPstatBin(jsonSVRDatabase);
+ // Read ACL resource from PS
+ ret = CBORPayloadToPstat(data, size, &gPstat);
+ OICFree(data);
}
/*
* If SVR database in persistent storage got corrupted or
* is not available for some reason, a default pstat is created
* which allows user to initiate pstat provisioning again.
*/
- if(!jsonSVRDatabase || !gPstat)
+ if ((OC_STACK_OK != ret) || !gPstat)
{
gPstat = GetPstatDefault();
}
+ VERIFY_NON_NULL(TAG, gPstat, FATAL);
+
+ //In case of Pstat's device id is empty, fill the device id as doxm's device id.
+ if(0 == memcmp(&gPstat->deviceID, &emptyUuid, sizeof(OicUuid_t)))
+ {
+ OicUuid_t doxmUuid = {.id={0}};
+ if(OC_STACK_OK == GetDoxmDeviceID(&doxmUuid))
+ {
+ memcpy(&gPstat->deviceID, &doxmUuid, sizeof(OicUuid_t));
+ }
+ }
// Instantiate 'oic.sec.pstat'
ret = CreatePstatResource();
- OICFree(jsonSVRDatabase);
+exit:
+ if (OC_STACK_OK != ret)
+ {
+ DeInitPstatResource();
+ }
return ret;
}
-/**
- * Perform cleanup for pstat resources.
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult DeInitPstatResource()
{
- if(gPstat != &gDefaultPstat)
+ if (gPstat != &gDefaultPstat)
{
DeletePstatBinData(gPstat);
gPstat = NULL;
return OCDeleteResource(gPstatHandle);
}
-
/**
* Function to restore pstat resurce to initial status.
* This function will use in case of error while ownership transfer
{
OIC_LOG(INFO, TAG, "PSTAT resource will revert back to initial status.");
- gPstat->cm = NORMAL;
- gPstat->tm = NORMAL;
+ gPstat->cm = (OicSecDpm_t)(gPstat->cm | TAKE_OWNER);
+ gPstat->tm = (OicSecDpm_t)(gPstat->tm & (~TAKE_OWNER));
gPstat->om = SINGLE_SERVICE_CLIENT_DRIVEN;
if(gPstat->sm && 0 < gPstat->smLen)
{
gPstat->sm[0] = SINGLE_SERVICE_CLIENT_DRIVEN;
}
- if(!UpdatePersistentStorage(gPstat))
+ if (!UpdatePersistentStorage(gPstat))
{
- OIC_LOG(ERROR, TAG, "Failed to revert DOXM in persistent storage");
+ OIC_LOG(ERROR, TAG, "Failed to revert PSTAT in persistent storage");
}
}
}
+
+OCStackResult SetPstatRownerId(const OicUuid_t* newROwner)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ uint8_t *cborPayload = NULL;
+ size_t size = 0;
+ OicUuid_t prevId = {.id={0}};
+
+ if(NULL == newROwner)
+ {
+ ret = OC_STACK_INVALID_PARAM;
+ }
+ if(NULL == gPstat)
+ {
+ ret = OC_STACK_NO_RESOURCE;
+ }
+
+ if(newROwner && gPstat)
+ {
+ memcpy(prevId.id, gPstat->rownerID.id, sizeof(prevId.id));
+ memcpy(gPstat->rownerID.id, newROwner->id, sizeof(newROwner->id));
+
+ ret = PstatToCBORPayload(gPstat, &cborPayload, &size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ ret = UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, cborPayload, size);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ OICFree(cborPayload);
+ }
+
+ return ret;
+
+exit:
+ OICFree(cborPayload);
+ memcpy(gPstat->rownerID.id, prevId.id, sizeof(prevId.id));
+ return ret;
+}
+
+/**
+ * This function returns the "isop" status of the device.
+ *
+ * @return true iff pstat.isop == 1, else false
+ */
+bool GetPstatIsop()
+{
+ return gPstat->isOp;
+}
+
+OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid)
+{
+ OCStackResult retVal = OC_STACK_ERROR;
+ if (gPstat)
+ {
+ *rowneruuid = gPstat->rownerID;
+ retVal = OC_STACK_OK;
+ }
+ return retVal;
+}
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <string.h>
#include "resourcemanager.h"
#include "securevirtualresourcetypes.h"
#include "aclresource.h"
#include "oic_string.h"
#include "logger.h"
#include "utlist.h"
-#include <string.h>
//#ifdef DIRECT_PAIRING
#include "pconfresource.h"
#include "dpairingresource.h"
//#endif // DIRECT_PAIRING
+#include "verresource.h"
#define TAG "SRM-RM"
#include "crlresource.h"
#endif // __WITH_X509__
-/**
- * This method is used by all secure resource modules to send responses to REST queries.
- *
- * @param ehRequest pointer to entity handler request data structure.
- * @param ehRet result code from entity handler.
- * @param rspPayload response payload in JSON.
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult SendSRMResponse(const OCEntityHandlerRequest *ehRequest,
- OCEntityHandlerResult ehRet, const char *rspPayload)
+ OCEntityHandlerResult ehRet, uint8_t *cborPayload, size_t size)
{
- OIC_LOG (DEBUG, TAG, "SRM sending SRM response");
+ OIC_LOG(DEBUG, TAG, "SRM sending SRM response");
OCEntityHandlerResponse response = {.requestHandle = NULL};
+ OCStackResult ret = OC_STACK_ERROR;
+
if (ehRequest)
{
OCSecurityPayload ocPayload = {.base = {.type = PAYLOAD_TYPE_INVALID}};
response.requestHandle = ehRequest->requestHandle;
response.resourceHandle = ehRequest->resource;
response.ehResult = ehRet;
- response.payload = (OCPayload*)(&ocPayload);
+ response.payload = (OCPayload *)(&ocPayload);
response.payload->type = PAYLOAD_TYPE_SECURITY;
- ((OCSecurityPayload*)response.payload)->securityData = (char *)rspPayload;
+ ((OCSecurityPayload *)response.payload)->securityData = cborPayload;
+ ((OCSecurityPayload *)response.payload)->payloadSize = size;
response.persistentBufferFlag = 0;
- return OCDoResponse(&response);
+ ret = OCDoResponse(&response);
}
- return OC_STACK_ERROR;
+ return ret;
}
-/**
- * Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult InitSecureResources( )
{
OCStackResult ret;
ret = InitDpairingResource();
}
//#endif // DIRECT_PAIRING
+ if(OC_STACK_OK == ret)
+ {
+ ret = InitVerResource();
+ }
if(OC_STACK_OK != ret)
{
//TODO: Update the default behavior if one of the SVR fails
return ret;
}
-/**
- * Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
- *
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult DestroySecureResources( )
{
DeInitACLResource();
DeInitPconfResource();
DeInitDpairingResource();
//#endif // DIRECT_PAIRING
+ DeInitVerResource();
return OC_STACK_OK;
}
PEContext_t g_policyEngineContext;
/**
- * @brief function to register provisoning API's response callback.
+ * Function to register provisoning API's response callback.
* @param respHandler response handler callback.
*/
void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler)
gSPResponseHandler = respHandler;
}
+void SetResourceRequestType(PEContext_t *context, const char *resourceUri)
+{
+ context->resourceType = GetSvrTypeFromUri(resourceUri);
+}
static void SRMSendUnAuthorizedAccessresponse(PEContext_t *context)
{
CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
- if(NULL == context ||
+ if (NULL == context ||
NULL == context->amsMgrContext->requestInfo)
{
OIC_LOG_V(ERROR, TAG, "%s : NULL Parameter(s)",__func__);
}
}
-
void SRMSendResponse(SRMAccessResponse_t responseVal)
{
OIC_LOG(DEBUG, TAG, "Sending response to remote device");
SetPolicyEngineState(&g_policyEngineContext, AWAITING_REQUEST);
}
-
/**
- * @brief Handle the request from the SRM.
- * @param endPoint [IN] Endpoint object from which the response is received.
- * @param requestInfo [IN] Information for the request.
- * @return NONE
+ * Handle the request from the SRM.
+ *
+ * @param endPoint object from which the response is received.
+ * @param requestInfo contains information for the request.
*/
void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requestInfo)
{
char newUri[MAX_URI_LENGTH + 1];
OICStrcpyPartial(newUri, MAX_URI_LENGTH + 1, requestInfo->info.resourceUri, position);
+ SetResourceRequestType(&g_policyEngineContext, newUri);
+
//New request are only processed if the policy engine state is AWAITING_REQUEST.
- if(AWAITING_REQUEST == g_policyEngineContext.state)
+ if (AWAITING_REQUEST == g_policyEngineContext.state)
{
OIC_LOG_V(DEBUG, TAG, "Processing request with uri, %s for method, %d",
requestInfo->info.resourceUri, requestInfo->method);
VERIFY_NON_NULL(TAG, gRequestHandler, ERROR);
- if(ACCESS_WAITING_FOR_AMS == response)
+ if (ACCESS_WAITING_FOR_AMS == response)
{
OIC_LOG(INFO, TAG, "Sending slow response");
}
/**
- * @brief Handle the response from the SRM.
- * @param endPoint [IN] The remote endpoint.
- * @param responseInfo [IN] Response information from the endpoint.
- * @return NONE
+ * Handle the response from the SRM.
+ *
+ * @param endPoint points to the remote endpoint.
+ * @param responseInfo contains response information from the endpoint.
*/
void SRMResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *responseInfo)
{
}
}
-
/**
- * @brief Handle the error from the SRM.
- * @param endPoint [IN] The remote endpoint.
- * @param errorInfo [IN] Error information from the endpoint.
- * @return NONE
+ * Handle the error from the SRM.
+ *
+ * @param endPoint is the remote endpoint.
+ * @param errorInfo contains error information from the endpoint.
*/
void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
{
}
}
-
-/**
- * @brief Register request and response callbacks.
- * Requests and responses are delivered in these callbacks.
- * @param reqHandler [IN] Request handler callback ( for GET,PUT ..etc)
- * @param respHandler [IN] Response handler callback.
- * @return
- * OC_STACK_OK - No errors; Success
- * OC_STACK_INVALID_PARAM - invalid parameter
- */
OCStackResult SRMRegisterHandler(CARequestCallback reqHandler,
CAResponseCallback respHandler,
CAErrorCallback errHandler)
return OC_STACK_OK;
}
-/**
- * @brief Register Persistent storage callback.
- * @param persistentStorageHandler [IN] Pointers to open, read, write, close & unlink handlers.
- * @return
- * OC_STACK_OK - No errors; Success
- * OC_STACK_INVALID_PARAM - Invalid parameter
- */
OCStackResult SRMRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler)
{
OIC_LOG(DEBUG, TAG, "SRMRegisterPersistentStorageHandler !!");
return OC_STACK_OK;
}
-/**
- * @brief Get Persistent storage handler pointer.
- * @return
- * The pointer to Persistent Storage callback handler
- */
-
OCPersistentStorage* SRMGetPersistentStorageHandler()
{
return gPersistentStorageHandler;
}
-
-/**
- * @brief Initialize all secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
- * @retval OC_STACK_OK for Success, otherwise some error value
- */
OCStackResult SRMInitSecureResources()
{
// TODO: temporarily returning OC_STACK_OK every time until default
return ret;
}
-/**
- * @brief Perform cleanup for secure resources ( /oic/sec/cred, /oic/sec/acl, /oic/sec/pstat etc).
- * @retval none
- */
void SRMDeInitSecureResources()
{
DestroySecureResources();
}
-/**
- * @brief Initialize Policy Engine.
- * @return OC_STACK_OK for Success, otherwise some error value.
- */
OCStackResult SRMInitPolicyEngine()
{
return InitPolicyEngine(&g_policyEngineContext);
}
-/**
- * @brief Cleanup Policy Engine.
- * @return none
- */
void SRMDeInitPolicyEngine()
{
return DeInitPolicyEngine(&g_policyEngineContext);
}
-/**
- * @brief Check the security resource URI.
- * @param uri [IN] Pointers to security resource URI.
- * @return true if the URI is one of security resources, otherwise false.
- */
bool SRMIsSecurityResourceURI(const char* uri)
{
if (!uri)
OIC_RSRC_PSTAT_URI,
OIC_RSRC_PCONF_URI,
OIC_RSRC_DPAIRING_URI,
+ OIC_RSRC_VER_URI,
};
// Remove query from Uri for resource string comparison
return false;
}
+
+/**
+ * Get the Secure Virtual Resource (SVR) type from the URI.
+ * @param uri [IN] Pointer to URI in question.
+ * @return The OicSecSvrType_t of the URI passed (note: if not a Secure Virtual
+ Resource, e.g. /a/light, will return "NOT_A_SVR_TYPE" enum value)
+ */
+static const char URI_QUERY_CHAR = '?';
+OicSecSvrType_t GetSvrTypeFromUri(const char* uri)
+{
+ if (!uri)
+ {
+ return NOT_A_SVR_RESOURCE;
+ }
+
+ // Remove query from Uri for resource string comparison
+ size_t uriLen = strlen(uri);
+ char *query = strchr (uri, URI_QUERY_CHAR);
+ if (query)
+ {
+ uriLen = query - uri;
+ }
+
+ size_t svrLen = 0;
+
+ svrLen = strlen(OIC_RSRC_ACL_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_ACL_URI, svrLen))
+ {
+ return OIC_R_ACL_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_AMACL_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_AMACL_URI, svrLen))
+ {
+ return OIC_R_AMACL_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_CRED_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_CRED_URI, svrLen))
+ {
+ return OIC_R_CRED_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_CRL_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_CRL_URI, svrLen))
+ {
+ return OIC_R_CRL_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_DOXM_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_DOXM_URI, svrLen))
+ {
+ return OIC_R_DOXM_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_DPAIRING_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_DPAIRING_URI, svrLen))
+ {
+ return OIC_R_DPAIRING_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_PCONF_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_PCONF_URI, svrLen))
+ {
+ return OIC_R_PCONF_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_PSTAT_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_PSTAT_URI, svrLen))
+ {
+ return OIC_R_PSTAT_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_SVC_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_SVC_URI, svrLen))
+ {
+ return OIC_R_SVC_TYPE;
+ }
+ }
+
+ svrLen = strlen(OIC_RSRC_SACL_URI);
+ if(uriLen == svrLen)
+ {
+ if(0 == strncmp(uri, OIC_RSRC_SACL_URI, svrLen))
+ {
+ return OIC_R_SACL_TYPE;
+ }
+ }
+
+ return NOT_A_SVR_RESOURCE;
+}
#include "securevirtualresourcetypes.h"
const char * SVR_DB_FILE_NAME = "oic_svr_db.json";
+const char * SVR_DB_DAT_FILE_NAME = "oic_svr_db.dat";
const char * OIC_MI_DEF = "oic.mi.def";
//AMACL
const char * OIC_RSRC_TYPE_SEC_ACL = "oic.sec.acl";
const char * OIC_RSRC_ACL_URI = "/oic/sec/acl";
const char * OIC_JSON_ACL_NAME = "acl";
+const char * OIC_JSON_ACLIST_NAME = "aclist";
+const char * OIC_JSON_ACES_NAME = "aces";
//Pstat
const char * OIC_RSRC_TYPE_SEC_PSTAT = "oic.sec.pstat";
const char * OIC_RSRC_TYPE_SEC_CRED = "oic.sec.cred";
const char * OIC_RSRC_CRED_URI = "/oic/sec/cred";
const char * OIC_JSON_CRED_NAME = "cred";
+const char * OIC_JSON_CREDS_NAME = "creds";
//CRL
const char * OIC_RSRC_TYPE_SEC_CRL = "oic.sec.crl";
const char * OIC_RSRC_CRL_URI = "/oic/sec/crl";
const char * OIC_JSON_CRL_NAME = "crl";
+
+//SACL
+const char * OIC_RSRC_TYPE_SEC_SACL = "oic.sec.sacl";
+const char * OIC_RSRC_SACL_URI = "/oic/sec/sacl";
+const char * OIC_JSON_SACL_NAME = "sacl";
+
//svc
const char * OIC_RSRC_TYPE_SEC_SVC = "oic.sec.svc";
const char * OIC_RSRC_SVC_URI = "/oic/sec/svc";
const char * OIC_RSRC_DPAIRING_URI = "/oic/sec/dpairing";
const char * OIC_JSON_DPAIRING_NAME = "dpairing";
+//version
+const char * OIC_RSRC_TYPE_SEC_VER = "oic.sec.ver";
+const char * OIC_RSRC_VER_URI = "/oic/sec/ver";
+const char * OIC_JSON_VER_NAME = "ver";
-const char * OIC_JSON_SUBJECT_NAME = "sub";
-const char * OIC_JSON_RESOURCES_NAME = "rsrc";
+const char * OIC_JSON_SUBJECT_NAME = "subject";
+const char * OIC_JSON_RESOURCES_NAME = "resources";
const char * OIC_JSON_AMSS_NAME = "amss";
-const char * OIC_JSON_PERMISSION_NAME = "perms";
+const char * OIC_JSON_AMS_NAME = "ams";
+const char * OIC_JSON_PERMISSION_NAME = "permission";
const char * OIC_JSON_OWNERS_NAME = "ownrs";
const char * OIC_JSON_OWNER_NAME = "ownr";
+const char * OIC_JSON_DEVOWNERID_NAME = "devowneruuid";
const char * OIC_JSON_OWNED_NAME = "owned";
const char * OIC_JSON_OXM_NAME = "oxm";
+const char * OIC_JSON_OXMS_NAME = "oxms";
const char * OIC_JSON_OXM_TYPE_NAME = "oxmtype";
const char * OIC_JSON_OXM_SEL_NAME = "oxmsel";
-const char * OIC_JSON_DEVICE_ID_FORMAT_NAME = "dvcidfrmt";
+const char * OIC_JSON_DEVICE_ID_FORMAT_NAME = "didformat";
const char * OIC_JSON_ISOP_NAME = "isop";
const char * OIC_JSON_COMMIT_HASH_NAME = "ch";
-const char * OIC_JSON_DEVICE_ID_NAME = "deviceid";
+const char * OIC_JSON_DEVICE_ID_NAME = "deviceuuid";
const char * OIC_JSON_CM_NAME = "cm";
const char * OIC_JSON_TM_NAME = "tm";
const char * OIC_JSON_OM_NAME = "om";
const char * OIC_JSON_SM_NAME = "sm";
const char * OIC_JSON_CREDID_NAME = "credid";
-const char * OIC_JSON_SUBJECTID_NAME = "subid";
+const char * OIC_JSON_SUBJECTID_NAME = "subjectuuid";
const char * OIC_JSON_ROLEIDS_NAME = "roleid";
-const char * OIC_JSON_CREDTYPE_NAME = "credtyp";
-const char * OIC_JSON_PUBLICDATA_NAME = "pbdata";
-const char * OIC_JSON_PRIVATEDATA_NAME = "pvdata";
+const char * OIC_JSON_CREDTYPE_NAME = "credtype";
+const char * OIC_JSON_PUBLICDATA_NAME = "publicdata";
+const char * OIC_JSON_PRIVATEDATA_NAME = "privatedata";
+const char * OIC_JSON_PUBDATA_NAME = "pubdata";
+const char * OIC_JSON_PRIVDATA_NAME = "privdata";
+const char * OIC_JSON_OPTDATA_NAME = "optdata";
const char * OIC_JSON_SERVICE_DEVICE_ID = "svcdid";
const char * OIC_JSON_SERVICE_TYPE = "svct";
-const char * OIC_JSON_PERIOD_NAME = "prd";
+const char * OIC_JSON_PERIOD_NAME = "period";
const char * OIC_JSON_PERIODS_NAME = "prds";
-const char * OIC_JSON_RECURRENCES_NAME = "recurs";
+const char * OIC_JSON_CRMS_NAME = "crms";
+const char * OIC_JSON_RECURRENCES_NAME = "recurrence";
const char * OIC_JSON_SUPPORTED_CRED_TYPE_NAME = "sct";
const char * OIC_JSON_DPC_NAME = "dpc";
const char * OIC_JSON_EDP_NAME = "edp";
const char * OIC_JSON_ROWNER_NAME = "rowner";
const char * OIC_JSON_PRM_NAME = "prm";
const char * OIC_JSON_SPM_NAME = "spm";
-const char * OIC_JSON_PDEVICE_ID_NAME = "pdeviceid";
+const char * OIC_JSON_PDEVICE_ID_NAME = "pdeviceuuid";
+const char * OIC_JSON_RLIST_NAME = "rlist";
+const char * OIC_JSON_HREF_NAME = "href";
+const char * OIC_JSON_REL_NAME = "rel";
+const char * OIC_JSON_RT_NAME = "rt";
+const char * OIC_JSON_IF_NAME = "if";
+const char * OIC_JSON_ROWNERID_NAME = "rowneruuid";
+const char * OIC_JSON_ENCODING_NAME = "encoding";
+const char * OIC_JSON_DATA_NAME = "data";
+const char * OIC_JSON_SEC_V_NAME = "secv";
+
+const char * OIC_JSON_EMPTY_STRING = "";
OicUuid_t WILDCARD_SUBJECT_ID = {"*"};
+OicUuid_t WILDCARD_SUBJECT_B64_ID = { .id = {'2', '2', '2', '2', '2', '2', '2', '2',
+ '2', '2', '2', '2', '2', '2', '2', '2' }};
size_t WILDCARD_SUBJECT_ID_LEN = 1;
const char * WILDCARD_RESOURCE_URI = "*";
const char * OXM_RANDOM_DEVICE_PIN = "oic.sec.doxm.rdp";
const char * OXM_MANUFACTURER_CERTIFICATE = "oic.sec.doxm.mfgcert";
+//Credential data encoding methods
+const char * OIC_SEC_ENCODING_BASE64 = "oic.sec.encoding.base64";
+const char * OIC_SEC_ENCODING_RAW = "oic.sec.encoding.raw";
+
const char * OIC_SEC_TRUE = "true";
const char * OIC_SEC_FALSE = "false";
const char * OIC_SEC_REST_QUERY_SEPARATOR = ";";
char OIC_SEC_REST_QUERY_DELIMETER = '=';
+//Security Version
+const char * DEFAULT_SEC_VERSION = "0.0.0";
+
#define TAG "SRM-UTILITY"
-/**
- * This method initializes the OicParseQueryIter_t struct
- *
- *@param query - REST query, to be parsed
- *@param parseIter - OicParseQueryIter_t struct, to be initialized
- *
- */
-void ParseQueryIterInit(unsigned char * query, OicParseQueryIter_t * parseIter)
+void ParseQueryIterInit(const unsigned char * query, OicParseQueryIter_t * parseIter)
{
- OIC_LOG (INFO, TAG, "Initializing coap iterator");
- if((NULL == query) || (NULL == parseIter))
+ OIC_LOG(INFO, TAG, "Initializing coap iterator");
+ if ((NULL == query) || (NULL == parseIter))
+ {
return;
+ }
parseIter->attrPos = NULL;
parseIter->attrLen = 0;
parseIter->valPos = NULL;
parseIter->valLen = 0;
- coap_parse_iterator_init(query, strlen((char *)query),
- (unsigned char *)OIC_SEC_REST_QUERY_SEPARATOR, (unsigned char *) "", 0, &parseIter->pi);
+ coap_parse_iterator_init((unsigned char *)query, strlen((char *)query),
+ (unsigned char *)OIC_SEC_REST_QUERY_SEPARATOR,
+ (unsigned char *) "", 0, &parseIter->pi);
}
-/**
- * This method fills the OicParseQueryIter_t struct with next REST query's
- * attribute's and value's information
- *
- *@param parseIter - OicParseQueryIter_t struct, has next query's attribute's & value's info
- *
- * @retval
- * OicParseQueryIter_t * - has parsed query info
- * NULL - has no query to parse
- */
OicParseQueryIter_t * GetNextQuery(OicParseQueryIter_t * parseIter)
{
- OIC_LOG (INFO, TAG, "Getting Next Query");
- if(NULL == parseIter)
+ OIC_LOG(INFO, TAG, "Getting Next Query");
+ if (NULL == parseIter)
+ {
return NULL;
+ }
unsigned char * qrySeg = NULL;
char * delimPos;
- //Get the next query. Querys are separated by OIC_SEC_REST_QUERY_SEPARATOR
+ // Get the next query. Querys are separated by OIC_SEC_REST_QUERY_SEPARATOR.
qrySeg = coap_parse_next(&parseIter->pi);
- if(qrySeg)
+ if (qrySeg)
{
delimPos = strchr((char *)qrySeg, OIC_SEC_REST_QUERY_DELIMETER);
- if(delimPos)
+ if (delimPos)
{
parseIter->attrPos = parseIter->pi.pos;
parseIter->attrLen = (unsigned char *)delimPos - parseIter->pi.pos;
return NULL;
}
-
// TODO This functionality is replicated in all SVR's and therefore we need
// to encapsulate it in a common method. However, this may not be the right
// file for this method.
-OCStackResult AddUuidArray(cJSON* jsonRoot, const char* arrayItem,
- size_t *numUuids, OicUuid_t** uuids )
+OCStackResult AddUuidArray(const cJSON* jsonRoot, const char* arrayItem,
+ size_t *numUuids, OicUuid_t** uuids)
{
size_t idxx = 0;
- cJSON* jsonObj = cJSON_GetObjectItem(jsonRoot, arrayItem);
+ cJSON* jsonObj = cJSON_GetObjectItem((cJSON *)jsonRoot, arrayItem);
VERIFY_NON_NULL(TAG, jsonObj, ERROR);
VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
outLen = 0;
b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
- sizeof(base64Buff), &outLen);
+ sizeof(base64Buff), &outLen);
VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof((*uuids)[idxx].id)),
- ERROR);
+ ERROR);
memcpy((*uuids)[idxx].id, base64Buff, outLen);
} while ( ++idxx < *numUuids);
}
}
+OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid)
+{
+ if(NULL == uuid || NULL == strUuid || NULL != *strUuid)
+ {
+ OIC_LOG(ERROR, TAG, "ConvertUuidToStr : Invalid param");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ size_t uuidIdx = 0;
+ size_t urnIdx = 0;
+ const size_t urnBufSize = (UUID_LENGTH * 2) + 4 + 1;
+ char* convertedUrn = (char*)OICCalloc(urnBufSize, sizeof(char));
+ VERIFY_NON_NULL(TAG, convertedUrn, ERROR);
+
+ for(uuidIdx=0, urnIdx=0; uuidIdx < UUID_LENGTH && urnIdx < urnBufSize; uuidIdx++, urnIdx+=2)
+ {
+ // canonical format for UUID has '8-4-4-4-12'
+ if(uuidIdx==4 || uuidIdx==6 || uuidIdx==8 || uuidIdx==10)
+ {
+ snprintf(convertedUrn + urnIdx, 2, "%c", '-');
+ urnIdx++;
+ }
+ snprintf(convertedUrn + urnIdx, 3, "%02x", (uint8_t)(uuid->id[uuidIdx]));
+ }
+ convertedUrn[urnBufSize - 1] = '\0';
+
+ *strUuid = convertedUrn;
+ return OC_STACK_OK;
+
+exit:
+ return OC_STACK_NO_MEMORY;
+}
+
+OCStackResult ConvertStrToUuid(const char* strUuid, OicUuid_t* uuid)
+{
+ if(NULL == strUuid || NULL == uuid)
+ {
+ OIC_LOG(ERROR, TAG, "ConvertStrToUuid : Invalid param");
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ size_t urnIdx = 0;
+ size_t uuidIdx = 0;
+ size_t strUuidLen = 0;
+ char convertedUuid[UUID_LENGTH * 2] = {0};
+
+ strUuidLen = strlen(strUuid);
+ if(0 == strUuidLen)
+ {
+ OIC_LOG(INFO, TAG, "The empty string detected, The UUID will be converted to "\
+ "\"00000000-0000-0000-0000-000000000000\"");
+ }
+ else if(UUID_LENGTH * 2 + 4 == strUuidLen)
+ {
+ for(uuidIdx=0, urnIdx=0; uuidIdx < UUID_LENGTH ; uuidIdx++, urnIdx+=2)
+ {
+ if(*(strUuid + urnIdx) == '-')
+ {
+ urnIdx++;
+ }
+ sscanf(strUuid + urnIdx, "%2hhx", &convertedUuid[uuidIdx]);
+ }
+ }
+ else
+ {
+ OIC_LOG(ERROR, TAG, "Invalid string uuid format, Please set the uuid as correct format");
+ OIC_LOG(ERROR, TAG, "e.g) \"72616E64-5069-6E44-6576-557569643030\" (4-2-2-2-6)");
+ OIC_LOG(ERROR, TAG, "e.g) \"\"");
+
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ memcpy(uuid->id, convertedUuid, UUID_LENGTH);
+
+ return OC_STACK_OK;
+}
// limitations under the License.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdlib.h>
+#include <string.h>
#include "ocstack.h"
-#include "logger.h"
+#include "ocpayload.h"
#include "oic_malloc.h"
-#include "cJSON.h"
-#include "base64.h"
+#include "utlist.h"
+#include "payload_logging.h"
#include "resourcemanager.h"
#include "psinterface.h"
#include "svcresource.h"
-#include "utlist.h"
#include "srmresourcestrings.h"
#include "srmutility.h"
-#include <stdlib.h>
-#include <string.h>
+
+#include "security_internals.h"
#define TAG "SRM-SVC"
-OicSecSvc_t *gSvc = NULL;
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching belox max cbor size. */
+static const uint16_t CBOR_SIZE = 512;
+
+/** Max cbor size payload. */
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+/** SVC Map size - Number of mandatory items. */
+static const uint8_t SVC_MAP_SIZE = 3;
+
+static OicSecSvc_t *gSvc = NULL;
static OCResourceHandle gSvcHandle = NULL;
void DeleteSVCList(OicSecSvc_t* svc)
}
}
-/*
- * This internal method converts SVC data into JSON format.
- *
- * Note: Caller needs to invoke 'free' when finished done using
- * return string.
- */
-char * BinToSvcJSON(const OicSecSvc_t * svc)
+static size_t svcElementsCount(const OicSecSvc_t *secSvc)
{
- cJSON *jsonRoot = NULL;
- char *jsonStr = NULL;
+ size_t size = 0;
+ for (const OicSecSvc_t *svc = secSvc; svc; svc = svc->next)
+ {
+ size++;
+ }
+ return size;
+}
- if (svc)
+OCStackResult SVCToCBORPayload(const OicSecSvc_t *svc, uint8_t **cborPayload,
+ size_t *cborSize)
+{
+ if (NULL == svc || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
{
- jsonRoot = cJSON_CreateObject();
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ return OC_STACK_INVALID_PARAM;
+ }
- cJSON *jsonSvcArray = NULL;
- cJSON_AddItemToObject (jsonRoot, OIC_JSON_SVC_NAME, jsonSvcArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonSvcArray, ERROR);
+ size_t cborLen = *cborSize;
+ if (0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
+ }
+ *cborPayload = NULL;
+ *cborSize = 0;
- while(svc)
- {
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
+ int64_t cborEncoderResult = CborNoError;
+ OCStackResult ret = OC_STACK_ERROR;
+ CborEncoder encoder;
+ CborEncoder svcArray;
- cJSON *jsonSvc = cJSON_CreateObject();
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
- // Service Device Identity
- outLen = 0;
- b64Ret = b64Encode(svc->svcdid.id, sizeof(OicUuid_t), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
- cJSON_AddStringToObject(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID, base64Buff );
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
- // Service Type
- cJSON_AddNumberToObject (jsonSvc, OIC_JSON_SERVICE_TYPE, svc->svct);
+ // Create SVC Array
+ cborEncoderResult = cbor_encoder_create_array(&encoder, &svcArray, svcElementsCount(svc));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Create SVC Array.");
- // Owners
- cJSON *jsonOwnrArray = NULL;
- cJSON_AddItemToObject (jsonSvc, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray());
- VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
- for (unsigned int i = 0; i < svc->ownersLen; i++)
- {
- outLen = 0;
+ while (svc)
+ {
+ CborEncoder svcMap;
+ CborEncoder owners;
+
+ cborEncoderResult = cbor_encoder_create_map(&svcArray, &svcMap, SVC_MAP_SIZE);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Create SVC Map.");
+
+ // Service Device Identity
+ cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_SERVICE_DEVICE_ID,
+ strlen(OIC_JSON_SERVICE_DEVICE_ID));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Device Id.");
+ cborEncoderResult = cbor_encode_byte_string(&svcMap, (uint8_t *)svc->svcdid.id,
+ sizeof(svc->svcdid.id));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to ");
+
+ // Service Type
+ cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_SERVICE_TYPE,
+ strlen(OIC_JSON_SERVICE_TYPE));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Serv Type Tag.");
+ cborEncoderResult = cbor_encode_int(&svcMap, svc->svct);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Serv Type Value.");
+
+ // Owners
+ // TODO: Need to modification to single ROwner, (Currently SINGLE_SERVICE_CLIENT_DRIVEN only)
+ cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_OWNERS_NAME,
+ strlen(OIC_JSON_OWNERS_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Owners Tag.");
+ cborEncoderResult = cbor_encoder_create_array(&svcMap, &owners, svc->ownersLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Array.");
+ for (size_t i = 0; i < svc->ownersLen; i++)
+ {
+ cborEncoderResult = cbor_encode_byte_string(&owners, (uint8_t *)svc->owners[i].id,
+ sizeof(svc->owners[i].id));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Owners Value.");
+ }
+ cborEncoderResult = cbor_encoder_close_container(&svcMap, &owners);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Array.");
- b64Ret = b64Encode(svc->owners[i].id, sizeof(((OicUuid_t*)0)->id), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+ cborEncoderResult = cbor_encoder_close_container(&svcArray, &svcMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Map.");
- cJSON_AddItemToArray (jsonOwnrArray, cJSON_CreateString(base64Buff));
- }
+ svc = svc->next;
+ }
- // Attach current svc node to Svc Array
- cJSON_AddItemToArray(jsonSvcArray, jsonSvc);
- svc = svc->next;
- }
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &svcArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Array.");
- jsonStr = cJSON_PrintUnformatted(jsonRoot);
+ if (CborNoError == cborEncoderResult)
+ {
+ *cborPayload = outPayload;
+ *cborSize = encoder.ptr - outPayload;
+ ret = OC_STACK_OK;
}
exit:
- if (jsonRoot)
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
{
- cJSON_Delete(jsonRoot);
+ // reallocate and try again!
+ OICFree(outPayload);
+ outPayload = NULL;
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ cborEncoderResult = CborNoError;
+ ret = SVCToCBORPayload(svc, cborPayload, &cborLen);
+ *cborSize = cborLen;
}
- return jsonStr;
+
+ if (CborNoError != cborEncoderResult)
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *cborSize = 0;
+ *cborPayload = NULL;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
}
-/*
- * This internal method converts JSON SVC into binary SVC.
- */
-OicSecSvc_t * JSONToSvcBin(const char * jsonStr)
+OCStackResult CBORPayloadToSVC(const uint8_t *cborPayload, size_t size,
+ OicSecSvc_t **secSvc)
{
+ if (NULL == cborPayload || NULL == secSvc || NULL != *secSvc || 0 == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ *secSvc = NULL;
+
OCStackResult ret = OC_STACK_ERROR;
- OicSecSvc_t * headSvc = NULL;
- OicSecSvc_t * prevSvc = NULL;
- cJSON *jsonRoot = NULL;
- cJSON *jsonSvcArray = NULL;
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+ CborValue svcCbor = { .parser = NULL };
+ CborParser parser = { .end = NULL };
+ CborError cborFindResult = CborNoError;
- jsonRoot = cJSON_Parse(jsonStr);
- VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+ cbor_parser_init(cborPayload, size, 0, &parser, &svcCbor);
+ OicSecSvc_t *headSvc = NULL;
- jsonSvcArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME);
- VERIFY_NON_NULL(TAG, jsonSvcArray, INFO);
+ CborValue svcArray = { .parser = NULL };
+ cborFindResult = cbor_value_enter_container(&svcCbor, &svcArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter SVC Array.");
- if (cJSON_Array == jsonSvcArray->type)
+ while (cbor_value_is_valid(&svcArray))
{
- int numSvc = cJSON_GetArraySize(jsonSvcArray);
- int idx = 0;
+ CborValue svcMap = { .parser = NULL };
+ OicSecSvc_t *svc = (OicSecSvc_t *) OICCalloc(1, sizeof(OicSecSvc_t));
+ VERIFY_NON_NULL(TAG, svc, ERROR);
+ cborFindResult = cbor_value_enter_container(&svcArray, &svcMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter SVC Map.");
- VERIFY_SUCCESS(TAG, numSvc > 0, INFO);
- do
+ while (cbor_value_is_valid(&svcMap))
{
- cJSON *jsonSvc = cJSON_GetArrayItem(jsonSvcArray, idx);
- VERIFY_NON_NULL(TAG, jsonSvc, ERROR);
+ char* name = NULL;
+ size_t len = 0;
+ CborType type = CborInvalidType;
- OicSecSvc_t *svc = (OicSecSvc_t*)OICCalloc(1, sizeof(OicSecSvc_t));
- VERIFY_NON_NULL(TAG, svc, ERROR);
+ cborFindResult = cbor_value_dup_text_string(&svcMap, &name, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Name.");
+ cborFindResult = cbor_value_advance(&svcMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance.");
- headSvc = (headSvc) ? headSvc : svc;
- if (prevSvc)
+ type = cbor_value_get_type(&svcMap);
+ // Service Device Identity
+ if (0 == strcmp(OIC_JSON_SERVICE_DEVICE_ID, name))
{
- prevSvc->next = svc;
+ uint8_t *subjectId = NULL;
+ cborFindResult = cbor_value_dup_byte_string(&svcMap, &subjectId, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find SubjectId.");
+ memcpy(svc->svcdid.id, subjectId, len);
+ OICFree(subjectId);
}
-
- cJSON *jsonObj = NULL;
-
- unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
-
- // Service Device Identity
- jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
- outLen = 0;
- b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
- sizeof(base64Buff), &outLen);
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->svcdid.id)), ERROR);
- memcpy(svc->svcdid.id, base64Buff, outLen);
-
// Service Type
- jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_TYPE);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
- svc->svct = (OicSecSvcType_t)jsonObj->valueint;
-
- // Resource Owners
- jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_OWNERS_NAME);
- VERIFY_NON_NULL(TAG, jsonObj, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
-
- svc->ownersLen = (size_t)cJSON_GetArraySize(jsonObj);
- VERIFY_SUCCESS(TAG, svc->ownersLen > 0, ERROR);
- svc->owners = (OicUuid_t*)OICCalloc(svc->ownersLen, sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, (svc->owners), ERROR);
-
- size_t idxx = 0;
- do
+ if (0 == strcmp(OIC_JSON_SERVICE_TYPE, name))
{
- cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
- VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
- VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
-
- outLen = 0;
- b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
- sizeof(base64Buff), &outLen);
+ cborFindResult = cbor_value_get_int(&svcMap, (int *) &svc->svct);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find SVCT.");
+ }
- VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->owners[idxx].id)),
- ERROR);
- memcpy(svc->owners[idxx].id, base64Buff, outLen);
- } while ( ++idxx < svc->ownersLen);
+ // Owners -- Mandatory
+ if (0 == strcmp(OIC_JSON_OWNERS_NAME, name))
+ {
+ int i = 0;
+ CborValue owners = { .parser = NULL };
+
+ cborFindResult = cbor_value_get_array_length(&svcMap, &svc->ownersLen);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Owner Len.");
+ cborFindResult = cbor_value_enter_container(&svcMap, &owners);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter Owner Array.");
+ svc->owners = (OicUuid_t *)OICCalloc(svc->ownersLen, sizeof(*svc->owners));
+ VERIFY_NON_NULL(TAG, svc->owners, ERROR);
+
+ while (cbor_value_is_valid(&owners))
+ {
+ uint8_t *owner = NULL;
+ cborFindResult = cbor_value_dup_byte_string(&owners, &owner, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Owner Array Value.");
+ cborFindResult = cbor_value_advance(&owners);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance Owner Array.");
+ memcpy(svc->owners[i++].id, owner, len);
+ OICFree(owner);
+ }
+ }
+ if (CborMapType != type && cbor_value_is_valid(&svcMap))
+ {
+ cborFindResult = cbor_value_advance(&svcMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance SVC.");
+ }
+ OICFree(name);
+ }
- prevSvc = svc;
- } while( ++idx < numSvc);
+ svc->next = NULL;
+ if (NULL == headSvc)
+ {
+ headSvc = svc;
+ }
+ else
+ {
+ OicSecSvc_t *temp = headSvc;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = svc;
+ }
+ if (cbor_value_is_valid(&svcArray))
+ {
+ cborFindResult = cbor_value_advance(&svcArray);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Name.");
+ }
}
-
+ *secSvc = headSvc;
ret = OC_STACK_OK;
exit:
- cJSON_Delete(jsonRoot);
- if (OC_STACK_OK != ret)
+ if (CborNoError != cborFindResult)
{
DeleteSVCList(headSvc);
headSvc = NULL;
+ *secSvc = NULL;
+ ret = OC_STACK_ERROR;
}
- return headSvc;
+ return ret;
}
-static OCEntityHandlerResult HandleSVCGetRequest (const OCEntityHandlerRequest * ehRequest)
+static OCEntityHandlerResult HandleSVCGetRequest(const OCEntityHandlerRequest * ehRequest)
{
// Convert SVC data into JSON for transmission
- char* jsonStr = BinToSvcJSON(gSvc);
-
- OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
+ size_t size = 0;
+ uint8_t *cborSvc = NULL;
+ OCStackResult res = SVCToCBORPayload(gSvc, &cborSvc, &size);
+ OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
// Send response payload to request originator
- SendSRMResponse(ehRequest, ehRet, jsonStr);
-
- OICFree(jsonStr);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, cborSvc, size))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleSVCGetRequest");
+ }
+ OICFree(cborSvc);
OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
return ehRet;
}
-static OCEntityHandlerResult HandleSVCPostRequest (const OCEntityHandlerRequest * ehRequest)
+static OCEntityHandlerResult HandleSVCPostRequest(const OCEntityHandlerRequest * ehRequest)
{
OCEntityHandlerResult ehRet = OC_EH_ERROR;
-
- // Convert JSON SVC data into binary. This will also validate the SVC data received.
- OicSecSvc_t* newSvc = JSONToSvcBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
-
- if (newSvc)
+ uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
+ size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
+ if (payload)
{
- // Append the new SVC to existing SVC
- LL_APPEND(gSvc, newSvc);
-
- // Convert SVC data into JSON for update to persistent storage
- char *jsonStr = BinToSvcJSON(gSvc);
- if (jsonStr)
+ // Convert CBOR SVC data into SVC. This will also validate the SVC data received.
+ OicSecSvc_t *newSvc = NULL;
+ OCStackResult res = CBORPayloadToSVC(payload, size, &newSvc);
+ if (newSvc && res == OC_STACK_OK)
{
- cJSON *jsonSvc = cJSON_Parse(jsonStr);
- OICFree(jsonStr);
-
- if ((jsonSvc) &&
- (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_SVC_NAME, jsonSvc)))
+ // Append the new SVC to existing SVC
+ LL_APPEND(gSvc, newSvc);
+
+ // Convert SVC data into JSON for update to persistent storage
+ size_t size = 0;
+ uint8_t *cborPayload = NULL;
+ res = SVCToCBORPayload(gSvc, &cborPayload, &size);
+ if (cborPayload && OC_STACK_OK == res &&
+ UpdateSecureResourceInPS(OIC_JSON_SVC_NAME, cborPayload, size) == OC_STACK_OK)
{
ehRet = OC_EH_RESOURCE_CREATED;
}
- cJSON_Delete(jsonSvc);
+ OICFree(cborPayload);
}
}
// Send payload to request originator
- SendSRMResponse(ehRequest, ehRet, NULL);
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleSVCPostRequest");
+ }
OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
return ehRet;
}
-/*
+/**
* This internal method is the entity handler for SVC resources and
* will handle REST request (GET/PUT/POST/DEL) for them.
*/
-OCEntityHandlerResult SVCEntityHandler (OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest,
- void* callbackParameter)
+static OCEntityHandlerResult SVCEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void* callbackParameter)
{
(void) callbackParameter;
OCEntityHandlerResult ehRet = OC_EH_ERROR;
default:
ehRet = OC_EH_ERROR;
- SendSRMResponse(ehRequest, ehRet, NULL);
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
}
}
return ehRet;
}
-/*
+/**
* This internal method is used to create '/oic/sec/svc' resource.
*/
-OCStackResult CreateSVCResource()
+static OCStackResult CreateSVCResource()
{
- OCStackResult ret;
-
- ret = OCCreateResource(&gSvcHandle,
- OIC_RSRC_TYPE_SEC_SVC,
- OIC_MI_DEF,
- OIC_RSRC_SVC_URI,
- SVCEntityHandler,
- NULL,
- OC_OBSERVABLE);
+ OCStackResult ret = OCCreateResource(&gSvcHandle,
+ OIC_RSRC_TYPE_SEC_SVC,
+ OIC_MI_DEF,
+ OIC_RSRC_SVC_URI,
+ SVCEntityHandler,
+ NULL,
+ OC_OBSERVABLE);
if (OC_STACK_OK != ret)
{
- OIC_LOG (FATAL, TAG, "Unable to instantiate SVC resource");
+ OIC_LOG(FATAL, TAG, "Unable to instantiate SVC resource");
DeInitSVCResource();
}
return ret;
}
-
OCStackResult InitSVCResource()
{
OCStackResult ret = OC_STACK_ERROR;
- OIC_LOG_V (DEBUG, TAG, "Begin %s ", __func__ );
+ OIC_LOG_V(DEBUG, TAG, "Begin %s ", __func__ );
- // Read SVC resource from PS
- char* jsonSVRDatabase = GetSVRDatabase();
+ uint8_t *data = NULL;
+ size_t size = 0;
+ ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_SVC_NAME, &data, &size);
+ // If database read failed
+ if (ret != OC_STACK_OK)
+ {
+ OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
+ }
- if (jsonSVRDatabase)
+ if (data)
{
- // Convert JSON SVC into binary format
- gSvc = JSONToSvcBin(jsonSVRDatabase);
- OICFree(jsonSVRDatabase);
+ // Convert CBOR SVC into binary format
+ ret = CBORPayloadToSVC(data, size, &gSvc);
+ if (ret != OC_STACK_OK)
+ {
+ OIC_LOG (DEBUG, TAG, " ConvertCBOR SVC into binary format failed");
+ }
+ OICFree(data);
}
// Instantiate 'oic.sec.svc'
DeInitSVCResource();
}
- OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ret);
+ OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__ , ret);
return ret;
}
-/**
- * Perform cleanup for SVC resources.
- *
- * @retval none
- */
void DeInitSVCResource()
{
OCDeleteResource(gSvcHandle);
DeleteSVCList(gSvc);
gSvc = NULL;
}
-
--- /dev/null
+/* *****************************************************************
+ *
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * *****************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "logger.h"
+#include "payload_logging.h"
+#include "ocpayload.h"
+#include "cainterface.h"
+#include "ocserverrequest.h"
+#include "resourcemanager.h"
+#include "verresource.h"
+#include "doxmresource.h"
+#include "psinterface.h"
+#include "srmresourcestrings.h"
+#include "securevirtualresourcetypes.h"
+#include "srmutility.h"
+
+#define TAG "SEC-VER"
+
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching belox max cbor size. */
+static const uint8_t CBOR_SIZE = 255;
+
+/** Max cbor size payload. */
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+/** VER Map size - Number of mandatory items. */
+static const uint8_t VER_MAP_SIZE = 2;
+
+static OCResourceHandle gVerHandle = NULL;
+
+/** Security version is mapped with iotivity release version */
+const char* SECURITY_VERSION = IOTIVITY_VERSION;
+
+static OicSecVer_t gVer =
+{
+ {0}, /* char *secv */
+ {.id = {0}}, /* OicUuid_t deviceID */
+};
+
+void DeleteVerBinData(OicSecVer_t* ver)
+{
+ if (ver)
+ {
+ //Clean ver itself
+ OICFree(ver);
+ }
+}
+
+OCStackResult VerToCBORPayload(const OicSecVer_t *ver, uint8_t **payload, size_t *size)
+{
+ if (NULL == ver || NULL == payload || NULL != *payload || NULL == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+ size_t cborLen = *size;
+ if (0 == cborLen)
+ {
+ cborLen = CBOR_SIZE;
+ }
+ *payload = NULL;
+ *size = 0;
+
+ OCStackResult ret = OC_STACK_ERROR;
+
+ CborEncoder encoder;
+ CborEncoder verMap;
+
+ int64_t cborEncoderResult = CborNoError;
+ uint8_t mapSize = VER_MAP_SIZE;
+ char* strUuid = NULL;
+
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+ cborEncoderResult |= cbor_encoder_create_map(&encoder, &verMap, mapSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Ver Map.");
+
+ //SecV -- Mandatory
+ cborEncoderResult |= cbor_encode_text_string(&verMap, OIC_JSON_SEC_V_NAME,
+ strlen(OIC_JSON_SEC_V_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SecV Tag.");
+ cborEncoderResult |= cbor_encode_text_string(&verMap, ver->secv, strlen(ver->secv));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SecV Value.");
+
+ //DeviceId -- Mandatory
+ cborEncoderResult = cbor_encode_text_string(&verMap, OIC_JSON_DEVICE_ID_NAME,
+ strlen(OIC_JSON_DEVICE_ID_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
+ ret = ConvertUuidToStr(&ver->deviceID, &strUuid);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
+ cborEncoderResult = cbor_encode_text_string(&verMap, strUuid, strlen(strUuid));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
+ OICFree(strUuid);
+ strUuid = NULL;
+
+
+ // Close ver(first) container
+ cborEncoderResult |= cbor_encoder_close_container(&encoder, &verMap);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing VerMap.");
+
+ if (CborNoError == cborEncoderResult)
+ {
+ *size = encoder.ptr - outPayload;
+ *payload = outPayload;
+ ret = OC_STACK_OK;
+ }
+exit:
+ if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+ {
+ OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
+ // reallocate and try again!
+ OICFree(outPayload);
+ // Since the allocated initial memory failed, double the memory.
+ cborLen += encoder.ptr - encoder.end;
+ OIC_LOG_V(DEBUG, TAG, "Ver reallocation size : %zd.", cborLen);
+ cborEncoderResult = CborNoError;
+ ret = VerToCBORPayload(ver, payload, &cborLen);
+ *size = cborLen;
+ }
+
+ if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
+ {
+ OICFree(outPayload);
+ outPayload = NULL;
+ *payload = NULL;
+ *size = 0;
+ ret = OC_STACK_ERROR;
+ }
+
+ return ret;
+}
+
+OCStackResult CBORPayloadToVer(const uint8_t *cborPayload, size_t size,
+ OicSecVer_t **secVer)
+{
+ if (NULL == cborPayload || NULL == secVer || NULL != *secVer || 0 == size)
+ {
+ return OC_STACK_INVALID_PARAM;
+ }
+
+ OCStackResult ret = OC_STACK_ERROR;
+ *secVer = NULL;
+ char *strUuid = NULL;
+
+ CborParser parser = { .end = NULL};
+ CborError cborFindResult = CborNoError;
+ size_t len = 0;
+ CborValue verCbor = { .parser = NULL };
+ cbor_parser_init(cborPayload, size, 0, &parser, &verCbor);
+ CborValue verMap = { .parser = NULL };
+ OicSecVer_t *ver = (OicSecVer_t *)OICCalloc(1, sizeof(OicSecVer_t));
+ VERIFY_NON_NULL(TAG, ver, ERROR);
+
+
+ cborFindResult = cbor_value_map_find_value(&verCbor, OIC_JSON_SEC_V_NAME, &verMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&verMap))
+ {
+ char *version = NULL;
+ cborFindResult = cbor_value_dup_text_string(&verMap, &version, &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Security Version Value.");
+ memcpy(ver->secv, version, len);
+ OICFree(version);
+ }
+
+ cborFindResult = cbor_value_map_find_value(&verCbor, OIC_JSON_DEVICE_ID_NAME, &verMap);
+ if (CborNoError == cborFindResult && cbor_value_is_text_string(&verMap))
+ {
+ cborFindResult = cbor_value_dup_text_string(&verMap, &strUuid , &len, NULL);
+ VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
+ ret = ConvertStrToUuid(strUuid , &ver->deviceID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ OICFree(strUuid );
+ strUuid = NULL;
+ }
+
+ *secVer = ver;
+ ret = OC_STACK_OK;
+
+exit:
+ if (CborNoError != cborFindResult)
+ {
+ OIC_LOG (ERROR, TAG, "CBORPayloadToVer failed!!!");
+ DeleteVerBinData(ver);
+ ret = OC_STACK_ERROR;
+ }
+ return ret;
+}
+
+static OCEntityHandlerResult HandleVerGetRequest (const OCEntityHandlerRequest * ehRequest)
+{
+ OCEntityHandlerResult ehRet = OC_EH_OK;
+
+ OIC_LOG(DEBUG, TAG, "Ver EntityHandle processing GET request");
+
+ /*
+ * For GET request return ver resource CBOR payload.
+ * For non-valid query return NULL json payload.
+ * The version is static built-in information, so VerToCBORPayload will
+ * return valid ver resource json.
+ */
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ if (OC_STACK_OK != VerToCBORPayload(&gVer, &payload, &size))
+ {
+ payload = NULL;
+ }
+
+ // Send response payload to request originator
+ if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
+ {
+ ehRet = OC_EH_ERROR;
+ OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleVerGetRequest");
+ }
+
+ OICFree(payload);
+
+ return ehRet;
+}
+
+OCEntityHandlerResult VerEntityHandler(OCEntityHandlerFlag flag,
+ OCEntityHandlerRequest * ehRequest,
+ void* callbackParam)
+{
+ (void)callbackParam;
+ OCEntityHandlerResult ehRet = OC_EH_ERROR;
+
+ if(NULL == ehRequest)
+ {
+ return ehRet;
+ }
+
+ if (flag & OC_REQUEST_FLAG)
+ {
+ OIC_LOG(DEBUG, TAG, "Flag includes OC_REQUEST_FLAG");
+
+ switch (ehRequest->method)
+ {
+ case OC_REST_GET:
+ ehRet = HandleVerGetRequest(ehRequest);
+ break;
+
+ default:
+ ehRet = OC_EH_ERROR;
+ SendSRMResponse(ehRequest, ehRet, NULL, 0);
+ break;
+ }
+ }
+
+ return ehRet;
+}
+
+OCStackResult CreateVerResource()
+{
+ OCStackResult ret = OCCreateResource(&gVerHandle,
+ OIC_RSRC_TYPE_SEC_VER,
+ OIC_MI_DEF,
+ OIC_RSRC_VER_URI,
+ VerEntityHandler,
+ NULL,
+ OC_SECURE);
+
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG (FATAL, TAG, "Unable to instantiate Ver resource");
+ DeInitVerResource();
+ }
+ return ret;
+}
+
+/**
+ * Get the security version.
+ *
+ * @return the version string of security.
+ */
+const char* GetSecVersion()
+{
+ OIC_LOG(DEBUG, TAG, "GetSecVersion");
+ return gVer.secv;
+}
+
+const OicSecVer_t* GetVerResourceData()
+{
+ return &gVer;
+}
+
+OCStackResult InitVerResource()
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ OICStrcpy(gVer.secv, MAX_VERSION_LEN, SECURITY_VERSION);
+
+ //Read device id from doxm
+ OicUuid_t deviceID = {.id={0}};
+ ret = GetDoxmDeviceID(&deviceID);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Error while retrieving doxm device ID");
+ return ret;
+ }
+ memcpy(&gVer.deviceID, &deviceID, sizeof(OicUuid_t));
+
+ //Instantiate 'oic.sec.ver'
+ ret = CreateVerResource();
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "Error while creating VER resource");
+ }
+
+ return ret;
+}
+
+OCStackResult DeInitVerResource()
+{
+ OCStackResult ret = OCDeleteResource(gVerHandle);
+
+ memset(&gVer, 0, sizeof(gVer));
+
+ if (OC_STACK_OK == ret)
+ {
+ return OC_STACK_OK;
+ }
+ else
+ {
+ return OC_STACK_ERROR;
+ }
+}
--- /dev/null
+# //******************************************************************
+# //
+# // Copyright 2015 Samsung Electronics All Rights Reserved.
+# //
+# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+# //
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# // http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# //
+# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+Import('env')
+
+tools_env = env.Clone()
+src_dir = tools_env.get('SRC_DIR')
+
+######################################################################
+# Build flags
+######################################################################
+tools_env.PrependUnique(CPPPATH = ['../../../../extlibs/cjson',
+ '../../stack/include',
+ '../../stack/include/internal',
+ '../../logger/include',
+ '../../../oc_logger/include',
+ '../../connectivity/api',
+ '../include',
+ '../include/internal',
+ '../../connectivity/lib/libcoap-4.1.1',
+
+ ])
+tools_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x'])
+tools_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+tools_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
+tools_env.PrependUnique(LIBS = ['oc', 'octbstack'])
+
+######################################################################
+# Source files and Targets
+######################################################################
+json2cbor = tools_env.Program('json2cbor', ['json2cbor.c'])
+Alias("json2cbor", [json2cbor])
+env.AppendTarget('json2cbor')
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <stdlib.h>
+#include <string.h>
+#include "cJSON.h"
+#include "base64.h"
+#include "cainterface.h"
+#include "ocstack.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
+#include "payload_logging.h"
+#include "secureresourcemanager.h"
+#include "srmresourcestrings.h"
+#include "srmutility.h"
+#include "aclresource.h"
+#include "pstatresource.h"
+#include "doxmresource.h"
+#include "amaclresource.h"
+#include "credresource.h"
+#include "svcresource.h"
+#include "security_internals.h"
+
+#define TAG "JSON2CBOR"
+#define MAX_RANGE ((size_t)-1)
+//SVR database buffer block size
+static const size_t DB_FILE_SIZE_BLOCK = 1023;
+
+static OicSecPstat_t* JSONToPstatBin(const char * jsonStr);
+static OicSecDoxm_t* JSONToDoxmBin(const char * jsonStr);
+static OicSecAcl_t *JSONToAclBin(const char * jsonStr);
+static OicSecSvc_t* JSONToSvcBin(const char * jsonStr);
+static OicSecAmacl_t* JSONToAmaclBin(const char * jsonStr);
+static OicSecCred_t* JSONToCredBin(const char * jsonStr);
+
+static size_t GetJSONFileSize(const char *jsonFileName)
+{
+ size_t size = 0;
+ size_t bytesRead = 0;
+ char buffer[DB_FILE_SIZE_BLOCK];
+ FILE* fp = fopen(jsonFileName, "r");
+ if (fp)
+ {
+ do
+ {
+ bytesRead = fread(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
+ if (bytesRead >=(MAX_RANGE - size))
+ {
+ fclose(fp);
+ return 0;
+ }
+ size += bytesRead;
+ } while (bytesRead > 0);
+ fclose(fp);
+ }
+ return size;
+}
+
+static void ConvertJsonToCBOR(const char *jsonFileName, const char *cborFileName)
+{
+ char *jsonStr = NULL;
+ FILE *fp = NULL;
+ FILE *fp1 = NULL;
+ uint8_t *aclCbor = NULL;
+ uint8_t *pstatCbor = NULL;
+ uint8_t *doxmCbor = NULL;
+ uint8_t *amaclCbor = NULL;
+ uint8_t *svcCbor = NULL;
+ uint8_t *credCbor = NULL;
+ cJSON *jsonRoot = NULL;
+ OCStackResult ret = OC_STACK_ERROR;
+ size_t size = GetJSONFileSize(jsonFileName);
+ if (0 == size)
+ {
+ OIC_LOG (ERROR, TAG, "Failed converting to JSON");
+ return;
+ }
+
+ jsonStr = (char *)OICMalloc(size + 1);
+ VERIFY_NON_NULL(TAG, jsonStr, FATAL);
+
+ fp = fopen(jsonFileName, "r");
+ if (fp)
+ {
+ size_t bytesRead = fread(jsonStr, 1, size, fp);
+ jsonStr[bytesRead] = '\0';
+
+ OIC_LOG_V(DEBUG, TAG, "Read %zu bytes", bytesRead);
+ fclose(fp);
+ fp = NULL;
+ }
+ else
+ {
+ OIC_LOG (ERROR, TAG, "Unable to open JSON file!!");
+ goto exit;
+ }
+
+ jsonRoot = cJSON_Parse(jsonStr);
+
+ cJSON *value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME);
+ //printf("ACL json : \n%s\n", cJSON_PrintUnformatted(value));
+ size_t aclCborSize = 0;
+ if (NULL != value)
+ {
+ OicSecAcl_t *acl = JSONToAclBin(jsonStr);
+ VERIFY_NON_NULL(TAG, acl, FATAL);
+ ret = AclToCBORPayload(acl, &aclCbor, &aclCborSize);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Failed converting Acl to Cbor Payload");
+ DeleteACLList(acl);
+ goto exit;
+ }
+ printf("ACL Cbor Size: %zd\n", aclCborSize);
+ DeleteACLList(acl);
+ }
+
+ value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME);
+ size_t pstatCborSize = 0;
+ if (NULL != value)
+ {
+ OicSecPstat_t *pstat = JSONToPstatBin(jsonStr);
+ VERIFY_NON_NULL(TAG, pstat, FATAL);
+ ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborSize);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Failed converting Pstat to Cbor Payload");
+ DeletePstatBinData(pstat);
+ goto exit;
+ }
+ printf("PSTAT Cbor Size: %zd\n", pstatCborSize);
+ DeletePstatBinData(pstat);
+ }
+ value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DOXM_NAME);
+ size_t doxmCborSize = 0;
+ if (NULL != value)
+ {
+ OicSecDoxm_t *doxm = JSONToDoxmBin(jsonStr);
+ VERIFY_NON_NULL(TAG, doxm, FATAL);
+ ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborSize);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Failed converting Doxm to Cbor Payload");
+ DeleteDoxmBinData(doxm);
+ goto exit;
+ }
+ printf("DOXM Cbor Size: %zd\n", doxmCborSize);
+ DeleteDoxmBinData(doxm);
+ }
+ value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
+ size_t amaclCborSize = 0;
+ if (NULL != value)
+ {
+ OicSecAmacl_t *amacl = JSONToAmaclBin(jsonStr);
+ VERIFY_NON_NULL(TAG, amacl, FATAL);
+ ret = AmaclToCBORPayload(amacl, &amaclCbor, &amaclCborSize);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Failed converting Amacl to Cbor Payload");
+ DeleteAmaclList(amacl);
+ goto exit;
+ }
+ printf("AMACL Cbor Size: %zd\n", amaclCborSize);
+ DeleteAmaclList(amacl);
+ }
+ value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME);
+ size_t svcCborSize = 0;
+ if (NULL != value)
+ {
+ OicSecSvc_t *svc = JSONToSvcBin(jsonStr);
+ VERIFY_NON_NULL(TAG, svc, FATAL);
+ ret = SVCToCBORPayload(svc, &svcCbor, &svcCborSize);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Failed converting Svc to Cbor Payload");
+ DeleteSVCList(svc);
+ goto exit;
+ }
+ printf("SVC Cbor Size: %zd\n", svcCborSize);
+ DeleteSVCList(svc);
+ }
+ value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME);
+ //printf("CRED json : \n%s\n", cJSON_PrintUnformatted(value));
+ size_t credCborSize = 0;
+ if (NULL != value)
+ {
+ OicSecCred_t *cred = JSONToCredBin(jsonStr);
+ VERIFY_NON_NULL(TAG, cred, FATAL);
+ ret = CredToCBORPayload(cred, &credCbor, &credCborSize);
+ if(OC_STACK_OK != ret)
+ {
+ OIC_LOG (ERROR, TAG, "Failed converting Cred to Cbor Payload");
+ DeleteCredList(cred);
+ goto exit;
+ }
+ printf("CRED Cbor Size: %zd\n", credCborSize);
+ DeleteCredList(cred);
+ }
+
+ CborEncoder encoder;
+ size_t cborSize = aclCborSize + pstatCborSize + doxmCborSize + svcCborSize + credCborSize + amaclCborSize;
+
+ printf("Total Cbor Size : %zd\n", cborSize);
+ cborSize += 255; // buffer margin for adding map and byte string
+ uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborSize);
+ VERIFY_NON_NULL(TAG, outPayload, ERROR);
+ cbor_encoder_init(&encoder, outPayload, cborSize, 0);
+ CborEncoder map;
+ CborError cborEncoderResult = cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating Main Map.");
+ if (aclCborSize > 0)
+ {
+ cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name.");
+ cborEncoderResult = cbor_encode_byte_string(&map, aclCbor, aclCborSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
+ }
+
+ if (pstatCborSize > 0)
+ {
+ cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
+ cborEncoderResult = cbor_encode_byte_string(&map, pstatCbor, pstatCborSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value.");
+ }
+ if (doxmCborSize > 0)
+ {
+ cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name.");
+ cborEncoderResult = cbor_encode_byte_string(&map, doxmCbor, doxmCborSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value.");
+ }
+ if (amaclCborSize > 0)
+ {
+ cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding AMACL Name.");
+ cborEncoderResult = cbor_encode_byte_string(&map, amaclCbor, amaclCborSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding AMACL Value.");
+ }
+ if (svcCborSize > 0)
+ {
+ cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
+ cborEncoderResult = cbor_encode_byte_string(&map, svcCbor, svcCborSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
+ }
+ if (credCborSize > 0)
+ {
+ cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
+ cborEncoderResult = cbor_encode_byte_string(&map, credCbor, credCborSize);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
+ }
+
+ cborEncoderResult = cbor_encoder_close_container(&encoder, &map);
+ VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Container.");
+
+ size_t s = encoder.ptr - outPayload;
+ OIC_LOG_V(DEBUG, TAG, "Payload size %zu", s);
+
+ fp1 = fopen(cborFileName, "w");
+ if (fp1)
+ {
+ size_t bytesWritten = fwrite(outPayload, 1, s, fp1);
+ if (bytesWritten == s)
+ {
+ OIC_LOG_V(DEBUG, TAG, "Written %zu bytes", bytesWritten);
+ }
+ else
+ {
+ OIC_LOG_V(ERROR, TAG, "Failed writing %zu bytes", s);
+ }
+ fclose(fp1);
+ fp1 = NULL;
+ }
+exit:
+
+ cJSON_Delete(jsonRoot);
+ OICFree(aclCbor);
+ OICFree(doxmCbor);
+ OICFree(pstatCbor);
+ OICFree(amaclCbor);
+ OICFree(svcCbor);
+ OICFree(credCbor);
+ OICFree(jsonStr);
+ return ;
+}
+
+OicSecAcl_t* JSONToAclBin(const char * jsonStr)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecAcl_t * headAcl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
+ cJSON *jsonRoot = NULL;
+
+ VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+
+ jsonRoot = cJSON_Parse(jsonStr);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ cJSON *jsonAclMap = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME);
+ VERIFY_NON_NULL(TAG, jsonAclMap, ERROR);
+
+ cJSON *jsonAclObj = NULL;
+
+ // aclist
+ jsonAclObj = cJSON_GetObjectItem(jsonAclMap, OIC_JSON_ACLIST_NAME);
+ VERIFY_NON_NULL(TAG, jsonAclObj, ERROR);
+
+ // aclist-aces
+ cJSON *jsonAclArray = NULL;
+ jsonAclArray = cJSON_GetObjectItem(jsonAclObj, OIC_JSON_ACES_NAME);
+ VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
+
+ if (cJSON_Array == jsonAclArray->type)
+ {
+
+ int numAcl = cJSON_GetArraySize(jsonAclArray);
+ int idx = 0;
+
+ VERIFY_SUCCESS(TAG, numAcl > 0, INFO);
+ do
+ {
+ cJSON *jsonAcl = cJSON_GetArrayItem(jsonAclArray, idx);
+ VERIFY_NON_NULL(TAG, jsonAcl, ERROR);
+
+ OicSecAcl_t *acl = NULL;
+ if(idx == 0)
+ {
+ acl = headAcl;
+ }
+ else
+ {
+ acl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
+ OicSecAcl_t *temp = headAcl;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = acl;
+ }
+
+ VERIFY_NON_NULL(TAG, acl, ERROR);
+
+ size_t jsonObjLen = 0;
+ cJSON *jsonObj = NULL;
+ jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_SUBJECTID_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+ if(strcmp(jsonObj->valuestring, WILDCARD_RESOURCE_URI) == 0)
+ {
+ acl->subject.id[0] = '*';
+ }
+ else
+ {
+ ret = ConvertStrToUuid(jsonObj->valuestring, &acl->subject);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ }
+ // Resources -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_RESOURCES_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
+
+ acl->resourcesLen = (size_t)cJSON_GetArraySize(jsonObj);
+
+ VERIFY_SUCCESS(TAG, acl->resourcesLen > 0, ERROR);
+ acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
+ VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
+
+ size_t idxx = 0;
+ do
+ {
+ cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
+ VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
+
+ size_t jsonRsrcObjLen = 0;
+ cJSON *jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_HREF_NAME);
+ VERIFY_NON_NULL(TAG, jsonRsrcObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonRsrcObj->type, ERROR);
+
+ jsonRsrcObjLen = strlen(jsonRsrcObj->valuestring) + 1;
+ acl->resources[idxx] = (char*)OICMalloc(jsonRsrcObjLen);
+
+ VERIFY_NON_NULL(TAG, (acl->resources[idxx]), ERROR);
+ OICStrcpy(acl->resources[idxx], jsonRsrcObjLen, jsonRsrcObj->valuestring);
+
+ } while ( ++idxx < acl->resourcesLen);
+
+ // Permissions -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_PERMISSION_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ acl->permission = jsonObj->valueint;
+ //Period -- Not Mandatory
+ cJSON *jsonPeriodObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_PERIOD_NAME);
+ if(jsonPeriodObj)
+ {
+ VERIFY_SUCCESS(TAG, cJSON_Array == jsonPeriodObj->type, ERROR);
+ acl->prdRecrLen = (size_t)cJSON_GetArraySize(jsonPeriodObj);
+ if(acl->prdRecrLen > 0)
+ {
+ acl->periods = (char**)OICCalloc(acl->prdRecrLen, sizeof(char*));
+ VERIFY_NON_NULL(TAG, acl->periods, ERROR);
+
+ cJSON *jsonPeriod = NULL;
+ for(size_t i = 0; i < acl->prdRecrLen; i++)
+ {
+ jsonPeriod = cJSON_GetArrayItem(jsonPeriodObj, i);
+ VERIFY_NON_NULL(TAG, jsonPeriod, ERROR);
+
+ jsonObjLen = strlen(jsonPeriod->valuestring) + 1;
+ acl->periods[i] = (char*)OICMalloc(jsonObjLen);
+ VERIFY_NON_NULL(TAG, acl->periods[i], ERROR);
+ OICStrcpy(acl->periods[i], jsonObjLen, jsonPeriod->valuestring);
+ }
+ }
+ }
+ //Recurrence -- Not mandatory
+ cJSON *jsonRecurObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_RECURRENCES_NAME);
+ if(jsonRecurObj)
+ {
+
+ VERIFY_SUCCESS(TAG, cJSON_Array == jsonRecurObj->type, ERROR);
+
+ if(acl->prdRecrLen > 0)
+ {
+ acl->recurrences = (char**)OICCalloc(acl->prdRecrLen, sizeof(char*));
+ VERIFY_NON_NULL(TAG, acl->recurrences, ERROR);
+
+ cJSON *jsonRecur = NULL;
+ for(size_t i = 0; i < acl->prdRecrLen; i++)
+ {
+ jsonRecur = cJSON_GetArrayItem(jsonRecurObj, i);
+ VERIFY_NON_NULL(TAG, jsonRecur, ERROR);
+ jsonObjLen = strlen(jsonRecur->valuestring) + 1;
+ acl->recurrences[i] = (char*)OICMalloc(jsonObjLen);
+ VERIFY_NON_NULL(TAG, acl->recurrences[i], ERROR);
+ OICStrcpy(acl->recurrences[i], jsonObjLen, jsonRecur->valuestring);
+ }
+ }
+ }
+
+ acl->next = NULL;
+
+ } while( ++idx < numAcl);
+ }
+
+
+ // rownerid
+ jsonAclObj = cJSON_GetObjectItem(jsonAclMap, OIC_JSON_ROWNERID_NAME);
+ VERIFY_NON_NULL(TAG, jsonAclObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonAclObj->type, ERROR);
+ ret = ConvertStrToUuid(jsonAclObj->valuestring, &headAcl->rownerID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ ret = OC_STACK_OK;
+
+exit:
+ cJSON_Delete(jsonRoot);
+ if (OC_STACK_OK != ret)
+ {
+ DeleteACLList(headAcl);
+ headAcl = NULL;
+ }
+ return headAcl;
+}
+
+OicSecDoxm_t* JSONToDoxmBin(const char * jsonStr)
+{
+ printf("IN JSONToDoxmBin\n");
+ if (NULL == jsonStr)
+ {
+ return NULL;
+ }
+
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecDoxm_t *doxm = NULL;
+ cJSON *jsonDoxm = NULL;
+ cJSON *jsonObj = NULL;
+
+ size_t jsonObjLen = 0;
+
+ cJSON *jsonRoot = cJSON_Parse(jsonStr);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ jsonDoxm = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DOXM_NAME);
+ VERIFY_NON_NULL(TAG, jsonDoxm, ERROR);
+
+ doxm = (OicSecDoxm_t *)OICCalloc(1, sizeof(OicSecDoxm_t));
+ VERIFY_NON_NULL(TAG, doxm, ERROR);
+
+ //OxmType -- not Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_TYPE_NAME);
+ if ((jsonObj) && (cJSON_Array == jsonObj->type))
+ {
+ doxm->oxmTypeLen = (size_t)cJSON_GetArraySize(jsonObj);
+ VERIFY_SUCCESS(TAG, doxm->oxmTypeLen > 0, ERROR);
+
+ doxm->oxmType = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(char *));
+ VERIFY_NON_NULL(TAG, (doxm->oxmType), ERROR);
+
+ for (size_t i = 0; i < doxm->oxmTypeLen ; i++)
+ {
+ cJSON *jsonOxmTy = cJSON_GetArrayItem(jsonObj, i);
+ VERIFY_NON_NULL(TAG, jsonOxmTy, ERROR);
+
+ jsonObjLen = strlen(jsonOxmTy->valuestring) + 1;
+ doxm->oxmType[i] = (char*)OICMalloc(jsonObjLen);
+ VERIFY_NON_NULL(TAG, doxm->oxmType[i], ERROR);
+ strncpy((char *)doxm->oxmType[i], (char *)jsonOxmTy->valuestring, jsonObjLen);
+ }
+ }
+
+ //Oxm -- not Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXMS_NAME);
+ if (jsonObj && cJSON_Array == jsonObj->type)
+ {
+ doxm->oxmLen = (size_t)cJSON_GetArraySize(jsonObj);
+ VERIFY_SUCCESS(TAG, doxm->oxmLen > 0, ERROR);
+
+ doxm->oxm = (OicSecOxm_t*)OICCalloc(doxm->oxmLen, sizeof(OicSecOxm_t));
+ VERIFY_NON_NULL(TAG, doxm->oxm, ERROR);
+
+ for (size_t i = 0; i < doxm->oxmLen ; i++)
+ {
+ cJSON *jsonOxm = cJSON_GetArrayItem(jsonObj, i);
+ VERIFY_NON_NULL(TAG, jsonOxm, ERROR);
+ doxm->oxm[i] = (OicSecOxm_t)jsonOxm->valueint;
+ }
+ }
+
+ //OxmSel -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OXM_SEL_NAME);
+ if (jsonObj)
+ {
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ doxm->oxmSel = (OicSecOxm_t)jsonObj->valueint;
+ }
+
+ //sct -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
+ if (jsonObj)
+ {
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ doxm->sct = (OicSecCredType_t)jsonObj->valueint;
+ }
+
+ //Owned -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_OWNED_NAME);
+ if (jsonObj)
+ {
+ VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR);
+ doxm->owned = jsonObj->valueint;
+ }
+
+ //DPC -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DPC_NAME);
+ if (jsonObj)
+ {
+ VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type), ERROR);
+ doxm->dpc = jsonObj->valueint;
+ }
+
+ //DeviceId -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DEVICE_ID_NAME);
+ if (jsonObj)
+ {
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+ if (cJSON_String == jsonObj->type)
+ {
+ //Check for empty string, in case DeviceId field has not been set yet
+ if (jsonObj->valuestring[0])
+ {
+ ret = ConvertStrToUuid(jsonObj->valuestring, &doxm->deviceID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ }
+ }
+ }
+
+ //rowner -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_ROWNERID_NAME);
+ if (true == doxm->owned)
+ {
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ }
+ if (jsonObj)
+ {
+ ret = ConvertStrToUuid(jsonObj->valuestring, &doxm->rownerID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ }
+
+ //Owner -- will be empty when device status is unowned.
+ jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DEVOWNERID_NAME);
+ if (true == doxm->owned)
+ {
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ }
+ if (jsonObj)
+ {
+ ret = ConvertStrToUuid(jsonObj->valuestring, &doxm->owner);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ }
+
+ ret = OC_STACK_OK;
+
+exit:
+ cJSON_Delete(jsonRoot);
+ if (OC_STACK_OK != ret)
+ {
+ DeleteDoxmBinData(doxm);
+ doxm = NULL;
+ }
+ printf("OUT JSONToDoxmBin\n");
+ return doxm;
+}
+
+OicSecPstat_t* JSONToPstatBin(const char * jsonStr)
+{
+ printf("IN JSONToPstatBin\n");
+ if(NULL == jsonStr)
+ {
+ return NULL;
+ }
+
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecPstat_t *pstat = NULL;
+ cJSON *jsonPstat = NULL;
+ cJSON *jsonObj = NULL;
+
+ cJSON *jsonRoot = cJSON_Parse(jsonStr);
+ VERIFY_NON_NULL(TAG, jsonRoot, INFO);
+
+ jsonPstat = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME);
+ VERIFY_NON_NULL(TAG, jsonPstat, INFO);
+
+ pstat = (OicSecPstat_t*)OICCalloc(1, sizeof(OicSecPstat_t));
+ VERIFY_NON_NULL(TAG, pstat, INFO);
+ jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_ISOP_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type) , ERROR);
+ pstat->isOp = jsonObj->valueint;
+
+ jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_DEVICE_ID_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+ ret = ConvertStrToUuid(jsonObj->valuestring, &pstat->deviceID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_ROWNERID_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+ ret = ConvertStrToUuid(jsonObj->valuestring, &pstat->rownerID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_CM_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ pstat->cm = (OicSecDpm_t)jsonObj->valueint;
+
+ jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_TM_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ pstat->tm = (OicSecDpm_t)jsonObj->valueint;
+
+ jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ pstat->om = (OicSecDpom_t)jsonObj->valueint;
+
+ jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_SM_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ pstat->smLen = 1;
+ pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+ pstat->sm[0] = (OicSecDpom_t)jsonObj->valueint;
+
+ ret = OC_STACK_OK;
+
+exit:
+ cJSON_Delete(jsonRoot);
+ if (OC_STACK_OK != ret)
+ {
+ OIC_LOG(ERROR, TAG, "JSONToPstatBin failed");
+ }
+ printf("OUT JSONToPstatBin\n");
+ return pstat;
+}
+
+OicSecCred_t * JSONToCredBin(const char * jsonStr)
+{
+ if (NULL == jsonStr)
+ {
+ OIC_LOG(ERROR, TAG,"JSONToCredBin jsonStr in NULL");
+ return NULL;
+ }
+
+ OicSecCred_t *headCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+ OCStackResult ret = OC_STACK_ERROR;
+ cJSON *jsonRoot = NULL;
+ VERIFY_NON_NULL(TAG, headCred, ERROR);
+
+ jsonRoot = cJSON_Parse(jsonStr);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ cJSON *jsonCredMap = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME);
+ VERIFY_NON_NULL(TAG, jsonCredMap, ERROR);
+
+ // creds
+ cJSON *jsonCredArray = NULL;
+ jsonCredArray = cJSON_GetObjectItem(jsonCredMap, OIC_JSON_CREDS_NAME);
+ VERIFY_NON_NULL(TAG, jsonCredArray, ERROR);
+
+ if (cJSON_Array == jsonCredArray->type)
+ {
+ int numCred = cJSON_GetArraySize(jsonCredArray);
+ VERIFY_SUCCESS(TAG, numCred > 0, ERROR);
+ int idx = 0;
+ size_t ownersLen = 0;
+ do
+ {
+ cJSON *jsonCred = cJSON_GetArrayItem(jsonCredArray, idx);
+ VERIFY_NON_NULL(TAG, jsonCred, ERROR);
+
+ OicSecCred_t *cred = NULL;
+ if(idx == 0)
+ {
+ cred = headCred;
+ }
+ else
+ {
+ cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+ OicSecCred_t *temp = headCred;
+ while (temp->next)
+ {
+ temp = temp->next;
+ }
+ temp->next = cred;
+ }
+ VERIFY_NON_NULL(TAG, cred, ERROR);
+
+ size_t jsonObjLen = 0;
+ cJSON *jsonObj = NULL;
+
+ //CredId -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDID_NAME);
+ if(jsonObj)
+ {
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ cred->credId = jsonObj->valueint;
+ }
+
+ //subject -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_SUBJECTID_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+ ret = ConvertStrToUuid(jsonObj->valuestring, &cred->subject);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ //CredType -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_CREDTYPE_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ cred->credType = (OicSecCredType_t)jsonObj->valueint;
+ //PrivateData is mandatory for some of the credential types listed below.
+ jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PRIVATEDATA_NAME);
+
+ if (NULL != jsonObj)
+ {
+ cJSON *jsonPriv = cJSON_GetObjectItem(jsonObj, OIC_JSON_DATA_NAME);
+ VERIFY_NON_NULL(TAG, jsonPriv, ERROR);
+ jsonObjLen = strlen(jsonPriv->valuestring);
+ cred->privateData.data = (uint8_t *)OICCalloc(1, jsonObjLen);
+ VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
+ memcpy(cred->privateData.data, jsonPriv->valuestring, jsonObjLen);
+ cred->privateData.len = jsonObjLen;
+ }
+#ifdef __WITH_X509__
+ //PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type.
+ jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PUBLICDATA_NAME);
+
+ if (NULL != jsonObj)
+ {
+ cJSON *jsonPub = cJSON_GetObjectItem(jsonObj, OIC_JSON_DATA_NAME);
+ VERIFY_NON_NULL(TAG, jsonPub, ERROR);
+ jsonObjLen = strlen(jsonPub->valuestring);
+ cred->publicData.data = (uint8_t *)OICCalloc(1, jsonObjLen);
+ VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR);
+ memcpy(cred->publicData.data, jsonPub->valuestring, jsonObjLen);
+ cred->publicData.len = jsonObjLen;
+ }
+#endif // __WITH_X509__
+ //Period -- Not Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PERIOD_NAME);
+ if(jsonObj && cJSON_String == jsonObj->type)
+ {
+ jsonObjLen = strlen(jsonObj->valuestring) + 1;
+ cred->period = (char *)OICMalloc(jsonObjLen);
+ VERIFY_NON_NULL(TAG, cred->period, ERROR);
+ strncpy(cred->period, jsonObj->valuestring, jsonObjLen);
+ }
+ cred->next = NULL;
+ } while( ++idx < numCred);
+ }
+
+ // rownerid
+ cJSON *jsonCredObj = cJSON_GetObjectItem(jsonCredMap, OIC_JSON_ROWNERID_NAME);
+ VERIFY_NON_NULL(TAG, jsonCredObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonCredObj->type, ERROR);
+ ret = ConvertStrToUuid(jsonCredObj->valuestring, &headCred->rownerID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+ ret = OC_STACK_OK;
+
+exit:
+
+ if (OC_STACK_OK != ret)
+ {
+ DeleteCredList(headCred);
+ headCred = NULL;
+ }
+ return headCred;
+}
+
+static OicSecSvc_t* JSONToSvcBin(const char * jsonStr)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecSvc_t * headSvc = NULL;
+ OicSecSvc_t * prevSvc = NULL;
+ cJSON *jsonRoot = NULL;
+ cJSON *jsonSvcArray = NULL;
+
+ VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+
+ jsonRoot = cJSON_Parse(jsonStr);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ jsonSvcArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME);
+ VERIFY_NON_NULL(TAG, jsonSvcArray, INFO);
+
+ if (cJSON_Array == jsonSvcArray->type)
+ {
+ int numSvc = cJSON_GetArraySize(jsonSvcArray);
+ int idx = 0;
+
+ VERIFY_SUCCESS(TAG, numSvc > 0, INFO);
+ do
+ {
+ cJSON *jsonSvc = cJSON_GetArrayItem(jsonSvcArray, idx);
+ VERIFY_NON_NULL(TAG, jsonSvc, ERROR);
+
+ OicSecSvc_t *svc = (OicSecSvc_t*)OICCalloc(1, sizeof(OicSecSvc_t));
+ VERIFY_NON_NULL(TAG, svc, ERROR);
+
+ headSvc = (headSvc) ? headSvc : svc;
+ if (prevSvc)
+ {
+ prevSvc->next = svc;
+ }
+
+ cJSON *jsonObj = NULL;
+ unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
+ uint32_t outLen = 0;
+ B64Result b64Ret = B64_OK;
+
+ // Service Device Identity
+ jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+ outLen = 0;
+ b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
+ sizeof(base64Buff), &outLen);
+ VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->svcdid.id)), ERROR);
+ memcpy(svc->svcdid.id, base64Buff, outLen);
+
+ // Service Type
+ jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_TYPE);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
+ svc->svct = (OicSecSvcType_t)jsonObj->valueint;
+
+ // Resource Owners
+ jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_OWNERS_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
+
+ svc->ownersLen = (size_t)cJSON_GetArraySize(jsonObj);
+ VERIFY_SUCCESS(TAG, svc->ownersLen > 0, ERROR);
+ svc->owners = (OicUuid_t*)OICCalloc(svc->ownersLen, sizeof(OicUuid_t));
+ VERIFY_NON_NULL(TAG, (svc->owners), ERROR);
+
+ size_t idxx = 0;
+ do
+ {
+ cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
+ VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
+ outLen = 0;
+ b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
+ sizeof(base64Buff), &outLen);
+
+ VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->owners[idxx].id)),
+ ERROR);
+ memcpy(svc->owners[idxx].id, base64Buff, outLen);
+ } while ( ++idxx < svc->ownersLen);
+
+ prevSvc = svc;
+ } while( ++idx < numSvc);
+ }
+
+ ret = OC_STACK_OK;
+
+exit:
+ cJSON_Delete(jsonRoot);
+ if (OC_STACK_OK != ret)
+ {
+ DeleteSVCList(headSvc);
+ headSvc = NULL;
+ }
+ return headSvc;
+}
+
+static OicSecAmacl_t* JSONToAmaclBin(const char * jsonStr)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ OicSecAmacl_t * headAmacl = (OicSecAmacl_t*)OICCalloc(1, sizeof(OicSecAmacl_t));
+
+ cJSON *jsonRoot = NULL;
+ cJSON *jsonAmacl = NULL;
+
+ VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+
+ jsonRoot = cJSON_Parse(jsonStr);
+ VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
+
+ jsonAmacl = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME);
+ VERIFY_NON_NULL(TAG, jsonAmacl, INFO);
+
+ cJSON *jsonObj = NULL;
+
+ // Resources -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_RESOURCES_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+
+ // Rlist
+ cJSON *jsonRlistArray = cJSON_GetObjectItem(jsonObj, OIC_JSON_RLIST_NAME);
+ VERIFY_NON_NULL(TAG, jsonRlistArray, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Array == jsonRlistArray->type, ERROR);
+
+ headAmacl->resourcesLen = (size_t)cJSON_GetArraySize(jsonRlistArray);
+ headAmacl->resources = (char**)OICCalloc(headAmacl->resourcesLen, sizeof(char*));
+ size_t idxx = 0;
+ do
+ {
+ cJSON *jsonRsrc = cJSON_GetArrayItem(jsonRlistArray, idxx);
+ VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
+
+ cJSON *jsonRsrcObj = cJSON_GetObjectItem(jsonRsrc, OIC_JSON_HREF_NAME);
+ VERIFY_NON_NULL(TAG, jsonRsrcObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonRsrcObj->type, ERROR);
+
+ size_t jsonRsrcObjLen = 0;
+ jsonRsrcObjLen = strlen(jsonRsrcObj->valuestring) + 1;
+ headAmacl->resources[idxx] = (char*)OICMalloc(jsonRsrcObjLen);
+ VERIFY_NON_NULL(TAG, (headAmacl->resources[idxx]), ERROR);
+ OICStrcpy(headAmacl->resources[idxx], jsonRsrcObjLen, jsonRsrcObj->valuestring);
+
+ } while ( ++idxx < headAmacl->resourcesLen);
+
+ // Ams -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_AMS_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
+
+ headAmacl->amssLen = (size_t)cJSON_GetArraySize(jsonObj);
+ VERIFY_SUCCESS(TAG, headAmacl->amssLen > 0, ERROR);
+ headAmacl->amss = (OicUuid_t*)OICCalloc(headAmacl->amssLen, sizeof(OicUuid_t));
+ VERIFY_NON_NULL(TAG, headAmacl->amss, ERROR);
+
+ idxx = 0;
+ do
+ {
+ cJSON *jsonAms = cJSON_GetArrayItem(jsonObj, idxx);
+ VERIFY_NON_NULL(TAG, jsonAms, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonAms->type, ERROR);
+
+ memcpy(headAmacl->amss[idxx].id, (OicUuid_t *)jsonAms->valuestring, strlen(jsonAms->valuestring));
+
+ } while ( ++idxx < headAmacl->amssLen);
+
+
+ // Rowner -- Mandatory
+ jsonObj = cJSON_GetObjectItem(jsonAmacl, OIC_JSON_ROWNERID_NAME);
+ VERIFY_NON_NULL(TAG, jsonObj, ERROR);
+ VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
+
+ ret = ConvertStrToUuid(jsonObj->valuestring, &headAmacl->rownerID);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ ret = OC_STACK_OK;
+
+exit:
+ cJSON_Delete(jsonRoot);
+ if (OC_STACK_OK != ret)
+ {
+ DeleteAmaclList(headAmacl);
+ headAmacl = NULL;
+ }
+ return headAmacl;
+}
+
+int main(int argc, char* argv[])
+{
+ if (argc == 3)
+ {
+ printf("JSON File Name: %s\n CBOR File Name: %s \n", argv[1], argv[2]);
+ ConvertJsonToCBOR(argv[1], argv[2]);
+ }
+ else
+ {
+ printf("This program requires two inputs:\n");
+ printf("1. First input is a json file tha will be converted to cbor. \n");
+ printf("2. Second input is a resulting cbor file that will store converted cbor. \n");
+ printf("\t json2cbor <json_file_name> <cbor_file_name>. \n");
+ }
+}
# '../../../../extlibs/tinydtls/',
'../include'
])
+
srmtest_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
srmtest_env.AppendUnique(LIBS = ['-lpthread'])
srmtest_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
# Source files and Targets
######################################################################
unittest = srmtest_env.Program('unittest', ['aclresourcetest.cpp',
+ 'amaclresourcetest.cpp',
'pstatresource.cpp',
'doxmresource.cpp',
'policyengine.cpp',
Alias("test", [unittest])
unittest_src_dir = src_dir + '/resource/csdk/security/unittest/'
-unittest_build_dir = env.get('BUILD_DIR') +'/resource/csdk/security/unittest'
+unittest_build_dir = env.get('BUILD_DIR') + 'resource/csdk/security/unittest'
+
+srmtest_env.AppendUnique(CPPDEFINES = ['SECURITY_BUILD_UNITTEST_DIR='+unittest_build_dir])
srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir,
unittest_src_dir + 'oic_unittest.json'))
srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir,
unittest_src_dir + 'oic_unittest_default_acl.json'))
+srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir,
+ unittest_src_dir + 'oic_unittest.dat'))
+srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir,
+ unittest_src_dir + 'oic_unittest_acl1.dat'))
+srmtest_env.Alias("install", srmtest_env.Install( unittest_build_dir,
+ unittest_src_dir + 'oic_unittest_default_acl.dat'))
+
env.AppendTarget('test')
if env.get('TEST') == '1':
target_os = env.get('TARGET_OS')
srmtest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs'])
ut = srmtest_env.Command ('ut', None, out_dir + '/resource/csdk/security/unittest/unittest')
AlwaysBuild ('ut')
-
#include <linux/limits.h>
#include <sys/stat.h>
#include "ocstack.h"
+#include "psinterface.h"
#include "ocpayload.h"
#include "oic_malloc.h"
#include "oic_string.h"
-#include "cJSON.h"
#include "cainterface.h"
#include "secureresourcemanager.h"
#include "securevirtualresourcetypes.h"
#include "srmtestcommon.h"
#include "srmutility.h"
#include "logger.h"
+#include "doxmresource.h"
+#include "ocpayload.h"
+#include "ocpayloadcbor.h"
+#include "payload_logging.h"
+#include "security_internals.h"
using namespace std;
#define TAG "SRM-ACL-UT"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern char * BinToAclJSON(const OicSecAcl_t * acl);
-extern OicSecAcl_t * JSONToAclBin(const char * jsonStr);
-extern void DeleteACLList(OicSecAcl_t* acl);
-OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl);
-OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest);
-#ifdef __cplusplus
-}
-#endif
-
-const char* JSON_FILE_NAME = "oic_unittest.json";
-const char* DEFAULT_ACL_JSON_FILE_NAME = "oic_unittest_default_acl.json";
-const char* ACL1_JSON_FILE_NAME = "oic_unittest_acl1.json";
+// These paths match jenkins build configuration.
+const char* DEFAULT_ACL_FILE_NAME = "/oic_unittest_default_acl.dat";
+const char* ACL1_FILE_NAME = "/oic_unittest_acl1.dat";
-#define NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON (2)
+#define NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT (1)
-// JSON Marshalling Tests
-TEST(ACLResourceTest, JSONMarshallingTests)
+TEST(ACLResourceTest, CBORDefaultACLConversion)
{
- char *jsonStr1 = ReadFile(ACL1_JSON_FILE_NAME);
- if (jsonStr1)
+ OicSecAcl_t *defaultAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
+ ASSERT_TRUE(defaultAcl != NULL);
+ uint8_t defaultAclSub[] = { 0x2a };
+ memcpy(defaultAcl->subject.id, defaultAclSub, sizeof(defaultAclSub));
+ defaultAcl->permission = 2;
+ const char *defaulAclRsrc[] = { "/oic/res", "/oic/d", "/oic/p", "/oic/res/types/d",
+ "/oic/ad", "/oic/sec/acl", "/oic/sec/doxm", "/oic/sec/pstat"};
+ defaultAcl->resourcesLen = 8;
+ defaultAcl->resources = (char **)OICCalloc(defaultAcl->resourcesLen, sizeof(char *));
+ ASSERT_TRUE(defaultAcl->resources != NULL);
+ for (size_t i = 0 ; i < defaultAcl->resourcesLen; i++)
{
- cJSON_Minify(jsonStr1);
- /* Workaround : cJSON_Minify does not remove all the unwanted characters
- from the end. Here is an attempt to remove those characters */
- int len = strlen(jsonStr1);
- while (len > 0)
- {
- if (jsonStr1[--len] == '}')
- {
- break;
- }
- }
- jsonStr1[len + 1] = 0;
+ defaultAcl->resources[i] = OICStrdup(defaulAclRsrc[i]);
+ ASSERT_TRUE(defaultAcl->resources[i] != NULL);
+ }
+ uint8_t defaultAclOwnrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
+ memcpy(defaultAcl->rownerID.id, defaultAclOwnrs, sizeof(defaultAclOwnrs));
+
+ size_t defaultAclSize = 0;
+ uint8_t *defaultPsStorage = NULL;
+ OCStackResult convRet = AclToCBORPayload(defaultAcl, &defaultPsStorage, &defaultAclSize);
+ EXPECT_EQ(OC_STACK_OK, convRet);
+ ASSERT_TRUE(defaultPsStorage != NULL);
+ EXPECT_NE(0, defaultAclSize);
+
+ OicSecAcl_t* convertedAcl = CBORPayloadToAcl(defaultPsStorage, defaultAclSize);
+ ASSERT_TRUE(convertedAcl != NULL);
+
+ EXPECT_EQ(defaultAcl->resourcesLen, convertedAcl->resourcesLen);
+ for(int i = 0; i < convertedAcl->resourcesLen; i++)
+ {
+ EXPECT_EQ(0, strcmp(defaultAcl->resources[i], convertedAcl->resources[i]));
+ }
- OicSecAcl_t * acl = JSONToAclBin(jsonStr1);
- EXPECT_TRUE(NULL != acl);
+ DeleteACLList(convertedAcl);
+ DeleteACLList(defaultAcl);
+ OICFree(defaultPsStorage);
+}
- char * jsonStr2 = BinToAclJSON(acl);
- EXPECT_TRUE(NULL != jsonStr2);
+TEST(ACLResourceTest, CBORACLConversion)
+{
+ OicSecAcl_t *secAcl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
+ ASSERT_TRUE(secAcl != NULL);
+ uint8_t subjectBytes[] = { 0x2a };
+ memcpy(secAcl->subject.id, subjectBytes, sizeof(subjectBytes));
+ secAcl->permission = 2;
+ const char *rsrc[] = { "/oic/res", "/oic/d", "/oic/p", "/oic/res/types/d",
+ "/oic/ad", "/oic/sec/acl"};
+ secAcl->resourcesLen = 6;
+ secAcl->resources = (char **)OICCalloc(secAcl->resourcesLen, sizeof(char *));
+ ASSERT_TRUE(secAcl->resources != NULL);
+ for (size_t i = 0 ; i < secAcl->resourcesLen; i++)
+ {
+ secAcl->resources[i] = OICStrdup(rsrc[i]);
+ ASSERT_TRUE(secAcl->resources[i] != NULL);
- EXPECT_STREQ(jsonStr1, jsonStr2);
+ }
- OICFree(jsonStr1);
- OICFree(jsonStr2);
- DeleteACLList(acl);
+ uint8_t ownrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
+ memcpy(secAcl->rownerID.id, ownrs, sizeof(ownrs));
+
+ OicSecAcl_t *secAcl1 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
+ ASSERT_TRUE(secAcl1 != NULL);
+ memcpy(secAcl1->subject.id, subjectBytes, sizeof(subjectBytes));
+ secAcl1->permission = 6;
+ const char *rsrc1[] = { "/oic/sec/doxm", "/oic/sec/pstat"};
+ secAcl1->resourcesLen = 2;
+ secAcl1->resources = (char **)OICCalloc(secAcl1->resourcesLen, sizeof(char *));
+ ASSERT_TRUE(secAcl1->resources != NULL);
+ for (size_t i = 0 ; i < secAcl1->resourcesLen; i++)
+ {
+ secAcl1->resources[i] = OICStrdup(rsrc1[i]);
+ ASSERT_TRUE(secAcl1->resources[i] != NULL);
+ }
+ memcpy(secAcl1->rownerID.id, ownrs, sizeof(ownrs));
+ secAcl->next = secAcl1;
+
+ OicSecAcl_t *secAcl2 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
+ ASSERT_TRUE(secAcl2 != NULL);
+ uint8_t subjectBytes1[] = {0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
+ 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
+ memcpy(secAcl2->subject.id, subjectBytes1, sizeof(subjectBytes1));
+ secAcl2->permission = 255;
+ const char *rsrc2[] = {"/oic/light", "/oic/fan" };
+ secAcl2->resourcesLen = 2;
+ secAcl2->resources = (char **)OICCalloc(secAcl2->resourcesLen, sizeof(char *));
+ ASSERT_TRUE(secAcl2->resources != NULL);
+ for (size_t i = 0 ; i < secAcl2->resourcesLen; i++)
+ {
+ secAcl2->resources[i] = OICStrdup(rsrc2[i]);
+ ASSERT_TRUE(secAcl2->resources[i] != NULL);
}
+ memcpy(secAcl2->rownerID.id, ownrs, sizeof(ownrs));
+ secAcl1->next = secAcl2;
+
+ OicSecAcl_t *secAcl3 = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
+ ASSERT_TRUE(secAcl3 != NULL);
+ uint8_t subjectBytes2[] = {0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
+ 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33};
+ memcpy(secAcl3->subject.id, subjectBytes2, sizeof(subjectBytes2));
+ secAcl3->permission = 255;
+ const char *rsrc3[] = {"/oic/light", "/oic/garage" };
+ secAcl3->resourcesLen = 2;
+ secAcl3->resources = (char **)OICCalloc(secAcl3->resourcesLen, sizeof(char *));
+ ASSERT_TRUE(secAcl3->resources != NULL);
+ for (size_t i = 0 ; i < secAcl3->resourcesLen; i++)
+ {
+ secAcl3->resources[i] = OICStrdup(rsrc3[i]);
+ ASSERT_TRUE(secAcl3->resources[i] != NULL);
+ }
+ memcpy(secAcl3->rownerID.id, ownrs, sizeof(ownrs));
+ secAcl2->next = secAcl3;
+ secAcl3->next = NULL;
+
+ size_t size = 0;
+ uint8_t *psStorage = NULL;
+ EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(secAcl, &psStorage, &size));
+ ASSERT_TRUE(NULL != psStorage);
+ OicSecAcl_t *acl = CBORPayloadToAcl(psStorage, size);
+ ASSERT_TRUE(NULL != acl);
+ EXPECT_EQ(2, acl->permission);
+ EXPECT_EQ(6 , acl->resourcesLen);
+ EXPECT_STREQ("/oic/res", acl->resources[0]);
+ DeleteACLList(acl);
+ OICFree(psStorage);
+ DeleteACLList(secAcl);
+}
+
+//InitResource Tests
+TEST(ACLResourceTest, InitAclResource)
+{
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, InitACLResource());
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitACLResource());
}
// Default ACL tests
TEST(ACLResourceTest, GetDefaultACLTests)
{
- // Read default ACL from the file
- char *jsonStr = ReadFile(DEFAULT_ACL_JSON_FILE_NAME);
- if (jsonStr)
- {
- OicSecAcl_t * acl = JSONToAclBin(jsonStr);
- EXPECT_TRUE(NULL != acl);
+ uint8_t *payload = NULL;
+ size_t size = 0;
- // Invoke API to generate default ACL
- OicSecAcl_t * defaultAcl = NULL;
- OCStackResult ret = GetDefaultACL(&defaultAcl);
- EXPECT_TRUE(NULL == defaultAcl);
+ ASSERT_TRUE(ReadCBORFile(DEFAULT_ACL_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
+ ASSERT_TRUE(payload != NULL);
- EXPECT_TRUE(OC_STACK_ERROR == ret);
+ OicSecAcl_t *psAcl = CBORPayloadToAcl(payload, size);
+ ASSERT_TRUE(psAcl != NULL);
- // Verify if the SRM generated default ACL matches with unit test default
- if (acl && defaultAcl)
+ OicSecAcl_t *acl = NULL;
+ EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl));
+ ASSERT_TRUE(acl != NULL);
+
+ // Verify if the SRM generated default ACL matches with unit test default
+ if (acl && psAcl)
+ {
+ EXPECT_TRUE(strcmp((char*)acl->subject.id, (char*)psAcl->subject.id) == 0);
+ EXPECT_EQ(acl->resourcesLen, psAcl->resourcesLen);
+ for (size_t i = 0; i < acl->resourcesLen; i++)
{
- EXPECT_TRUE(memcmp(&(acl->subject), &(defaultAcl->subject), sizeof(OicUuid_t)) == 0);
- EXPECT_EQ(acl->resourcesLen, defaultAcl->resourcesLen);
- for (size_t i = 0; i < acl->resourcesLen; i++)
- {
- EXPECT_EQ(strlen(acl->resources[i]), strlen(defaultAcl->resources[i]));
- EXPECT_TRUE(
- memcmp(acl->resources[i], defaultAcl->resources[i],
- strlen(acl->resources[i])) == 0);
- }
- EXPECT_EQ(acl->permission, defaultAcl->permission);
+ EXPECT_EQ(strlen(acl->resources[i]), strlen(psAcl->resources[i]));
+ EXPECT_TRUE(memcmp(acl->resources[i], psAcl->resources[i],
+ strlen(acl->resources[i])) == 0);
}
-
- // Perform cleanup
- DeleteACLList(acl);
- DeleteACLList(defaultAcl);
- OICFree(jsonStr);
+ EXPECT_EQ(acl->permission, psAcl->permission);
}
-}
+ DeleteACLList(psAcl);
+ DeleteACLList(acl);
+ DeInitACLResource();
+ OICFree(payload);
+}
// 'POST' ACL tests
TEST(ACLResourceTest, ACLPostTest)
{
- OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
-
// Read an ACL from the file
- char *jsonStr = ReadFile(ACL1_JSON_FILE_NAME);
- if (jsonStr)
- {
- static OCPersistentStorage ps = OCPersistentStorage();
+ uint8_t *payload = NULL;
+ size_t size = 0;
- SetPersistentHandler(&ps, true);
+ ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
+ ASSERT_TRUE(NULL != payload);
- // Create Entity Handler POST request payload
- ehReq.method = OC_REST_POST;
- ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
+ OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
+ ASSERT_TRUE(NULL != securityPayload);
- OCEntityHandlerResult ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_ERROR == ehRet);
+ static OCPersistentStorage ps = OCPersistentStorage();
+ SetPersistentHandler(&ps, true);
- // Convert JSON into OicSecAcl_t for verification
- OicSecAcl_t * acl = JSONToAclBin(jsonStr);
- EXPECT_TRUE(NULL != acl);
+ // Create Entity Handler POST request payload
+ OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
+ ehReq.method = OC_REST_POST;
+ ehReq.payload = (OCPayload *) securityPayload;
- // Verify if SRM contains ACL for the subject
- OicSecAcl_t* savePtr = NULL;
- const OicSecAcl_t* subjectAcl = GetACLResourceData(&(acl->subject), &savePtr);
- EXPECT_TRUE(NULL != subjectAcl);
+ ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
- // Perform cleanup
- DeleteACLList(acl);
- DeInitACLResource();
- OCPayloadDestroy(ehReq.payload);
- OICFree(jsonStr);
- }
-}
+ OicSecAcl_t *acl = CBORPayloadToAcl(payload, size);
+ ASSERT_TRUE(NULL != acl);
+
+ // Verify if SRM contains ACL for the subject
+ OicSecAcl_t *savePtr = NULL;
+ const OicSecAcl_t* subjectAcl = GetACLResourceData(&(acl->subject), &savePtr);
+ ASSERT_TRUE(NULL != subjectAcl);
+ // Perform cleanup
+ OICFree(payload);
+ OCPayloadDestroy((OCPayload *) securityPayload);
+ DeInitACLResource();
+ DeleteACLList(acl);
+}
// GetACLResource tests
TEST(ACLResourceTest, GetACLResourceTests)
{
- // gAcl is a pointer to the the global ACL used by SRM
- extern OicSecAcl_t *gAcl;
-
// Read an ACL from the file
- char *jsonStr = ReadFile(ACL1_JSON_FILE_NAME);
- if (jsonStr)
- {
- gAcl = JSONToAclBin(jsonStr);
- EXPECT_TRUE(NULL != gAcl);
+ static OCPersistentStorage ps = OCPersistentStorage();
+ SetPersistentHandler(&ps, true);
- // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
- const OicSecAcl_t* acl = NULL;
- OicSecAcl_t* savePtr = NULL;
- OicUuid_t subject = WILDCARD_SUBJECT_ID;
- int count = 0;
+ uint8_t *payload = NULL;
+ size_t size = 0;
- do
- {
- acl = GetACLResourceData(&subject, &savePtr);
- count = (NULL != acl) ? count + 1 : count;
- } while (acl != NULL);
+ ASSERT_TRUE(ReadCBORFile(ACL1_FILE_NAME, OIC_JSON_ACL_NAME, &payload, &size));
+ ASSERT_TRUE(payload != NULL);
- EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_JSON);
+ OicSecAcl_t *defaultPsAcl = CBORPayloadToAcl(payload, size);
+ ASSERT_TRUE(defaultPsAcl != NULL);
- /* Perform cleanup */
- DeleteACLList(gAcl);
- gAcl = NULL;
- OICFree(jsonStr);
- }
+ OicSecAcl_t *acl1 = NULL;
+ EXPECT_EQ(OC_STACK_OK, GetDefaultACL(&acl1));
+ ASSERT_TRUE(acl1 != NULL);
+ EXPECT_EQ(OC_STACK_OK, SetDefaultACL(acl1));
+
+ // Verify that ACL file contains 2 ACE entries for 'WILDCARD' subject
+ const OicSecAcl_t *acl = NULL;
+ OicSecAcl_t *savePtr = NULL;
+ OicUuid_t subject = WILDCARD_SUBJECT_ID;
+ int count = 0;
+
+ do
+ {
+ acl = GetACLResourceData(&subject, &savePtr);
+ count = (NULL != acl) ? count + 1 : count;
+ } while (acl != NULL);
+
+ EXPECT_EQ(count, NUM_ACE_FOR_WILDCARD_IN_ACL1_DAT);
+
+ /* Perform cleanup */
+ OICFree(payload);
+ DeleteACLList(defaultPsAcl);
+ DeInitACLResource();
}
static OCStackResult populateAcl(OicSecAcl_t *acl, int numRsrc)
{
- OCStackResult ret = OC_STACK_ERROR;
+ OCStackResult ret = OC_STACK_ERROR;
memcpy(acl->subject.id, "2222222222222222", sizeof(acl->subject.id));
acl->resourcesLen = (size_t)numRsrc;
acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
VERIFY_NON_NULL(TAG, acl->resources, ERROR);
acl->resources[0] = (char*)OICMalloc(strlen("/a/led")+1);
VERIFY_NON_NULL(TAG, acl->resources[0], ERROR);
- OICStrcpy(acl->resources[0], sizeof(acl->resources[0]), "/a/led");
+ OICStrcpy(acl->resources[0], strlen("/a/led")+1, "/a/led");
if(numRsrc == 2)
{
acl->resources[1] = (char*)OICMalloc(strlen("/a/fan")+1);
VERIFY_NON_NULL(TAG, acl->resources[1], ERROR);
- OICStrcpy(acl->resources[1], sizeof(acl->resources[1]), "/a/fan");
+ OICStrcpy(acl->resources[1], strlen("/a/fan")+1, "/a/fan");
}
acl->permission = 6;
- acl->ownersLen = 1;
- acl->owners = (OicUuid_t*)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, acl->owners, ERROR);
- memcpy(acl->owners->id, "1111111111111111", sizeof(acl->owners->id));
+ memcpy(acl->rownerID.id, "1111111111111111", sizeof(acl->rownerID.id));
ret = OC_STACK_OK;
exit:
//'DELETE' ACL test
TEST(ACLResourceTest, ACLDeleteWithSingleResourceTest)
{
- OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
- static OCPersistentStorage ps = OCPersistentStorage();
- char *jsonStr = NULL;
+ //Populate ACL
OicSecAcl_t acl = OicSecAcl_t();
- OicSecAcl_t* savePtr = NULL;
- const OicSecAcl_t* subjectAcl1 = NULL;
- const OicSecAcl_t* subjectAcl2 = NULL;
- OCEntityHandlerResult ehRet = OC_EH_ERROR;
- char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
+ EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
- SetPersistentHandler(&ps, true);
+ //GET CBOR POST payload
+ size_t size = 0;
+ uint8_t *payload = NULL;
+ EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
+ ASSERT_TRUE(NULL != payload);
- //Populate ACL
- VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 1)), ERROR);
+ // Security Payload
+ OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
+ ASSERT_TRUE(NULL != securityPayload);
- //GET json POST payload
- jsonStr = BinToAclJSON(&acl);
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+ static OCPersistentStorage ps = OCPersistentStorage();
+ SetPersistentHandler(&ps, true);
// Create Entity Handler POST request payload
+ OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
+ ehReq.payload = (OCPayload *) securityPayload;
ehReq.method = OC_REST_POST;
- ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
- ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_ERROR == ehRet);
+ ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
// Verify if SRM contains ACE for the subject
- savePtr = NULL;
- subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
- EXPECT_TRUE(NULL != subjectAcl1);
+ OicSecAcl_t* savePtr = NULL;
+ const OicSecAcl_t* subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
+ ASSERT_TRUE(NULL != subjectAcl1);
// Create Entity Handler DELETE request
ehReq.method = OC_REST_DELETE;
- ehReq.query = (char*)OICMalloc(strlen(query)+1);
- VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
+ char query[] = "subjectuuid=2222222222222222;resources=/a/led";
+ ehReq.query = (char *)OICMalloc(strlen(query)+1);
+ ASSERT_TRUE(NULL != ehReq.query);
OICStrcpy(ehReq.query, strlen(query)+1, query);
- ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_ERROR == ehRet);
+ ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
// Verify if SRM has deleted ACE for the subject
savePtr = NULL;
- subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
- EXPECT_TRUE(NULL == subjectAcl2);
+ const OicSecAcl_t* subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
+ ASSERT_TRUE(NULL == subjectAcl2);
-exit:
// Perform cleanup
- if(NULL != subjectAcl1)
- {
- DeInitACLResource();
- }
- OCPayloadDestroy(ehReq.payload);
+ DeInitACLResource();
OICFree(ehReq.query);
- OICFree(jsonStr);
-
+ OCPayloadDestroy((OCPayload *)securityPayload);
+ OICFree(payload);
}
TEST(ACLResourceTest, ACLDeleteWithMultiResourceTest)
{
- OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
- static OCPersistentStorage ps = OCPersistentStorage();
+ //Populate ACL
OicSecAcl_t acl = OicSecAcl_t();
- char *jsonStr = NULL;
- OicSecAcl_t* savePtr = NULL;
- const OicSecAcl_t* subjectAcl1 = NULL;
- const OicSecAcl_t* subjectAcl2 = NULL;
- OCEntityHandlerResult ehRet = OC_EH_ERROR;
- char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
+ EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 2));
- SetPersistentHandler(&ps, true);
+ //GET CBOR POST payload
+ size_t size = 0;
+ uint8_t *payload = NULL;
+ EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
+ ASSERT_TRUE(NULL != payload);
- //Populate ACL
- VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 2)), ERROR);
+ // Security Payload
+ OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
+ ASSERT_TRUE(NULL!= securityPayload);
- //GET json POST payload
- jsonStr = BinToAclJSON(&acl);
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+ static OCPersistentStorage ps = OCPersistentStorage();
+ SetPersistentHandler(&ps, true);
// Create Entity Handler POST request payload
+ OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
ehReq.method = OC_REST_POST;
- ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
- ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_ERROR == ehRet);
+ ehReq.payload = (OCPayload *)securityPayload;
+ ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
// Verify if SRM contains ACE for the subject with two resources
- savePtr = NULL;
- subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
- VERIFY_NON_NULL(TAG, subjectAcl1, ERROR);
- EXPECT_TRUE(subjectAcl1->resourcesLen == 2);
+ OicSecAcl_t* savePtr = NULL;
+ const OicSecAcl_t* subjectAcl1 = GetACLResourceData(&acl.subject, &savePtr);
+ ASSERT_TRUE(NULL != subjectAcl1);
+ EXPECT_EQ(2, subjectAcl1->resourcesLen);
// Create Entity Handler DELETE request
ehReq.method = OC_REST_DELETE;
- ehReq.query = (char*)OICMalloc(strlen(query)+1);
- VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
+ char query[] = "subjectuuid=2222222222222222;resources=/a/led";
+ ehReq.query = (char *)OICMalloc(strlen(query)+1);
+ ASSERT_TRUE(NULL != ehReq.query);
OICStrcpy(ehReq.query, strlen(query)+1, query);
- ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_ERROR == ehRet);
+ ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
// Verify if SRM contains ACL for the subject but only with one resource
savePtr = NULL;
- subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
- VERIFY_NON_NULL(TAG, subjectAcl2, ERROR);
- EXPECT_TRUE(subjectAcl2->resourcesLen == 1);
+ const OicSecAcl_t* subjectAcl2 = GetACLResourceData(&acl.subject, &savePtr);
+ ASSERT_TRUE(NULL != subjectAcl2);
+ EXPECT_EQ(1, subjectAcl2->resourcesLen);
-exit:
// Perform cleanup
- if(NULL != subjectAcl1)
- {
- DeInitACLResource();
- }
- OCPayloadDestroy(ehReq.payload);
+ OCPayloadDestroy((OCPayload *)securityPayload);
+ DeInitACLResource();
OICFree(ehReq.query);
- OICFree(jsonStr);
+ OICFree(payload);
}
//'GET' with query ACL test
-
TEST(ACLResourceTest, ACLGetWithQueryTest)
{
- OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
- static OCPersistentStorage ps = OCPersistentStorage();
+ //Populate ACL
OicSecAcl_t acl = OicSecAcl_t();
- char *jsonStr = NULL;
- OCEntityHandlerResult ehRet = OC_EH_ERROR;
- char query[] = "sub=MjIyMjIyMjIyMjIyMjIyMg==;rsrc=/a/led";
+ EXPECT_EQ(OC_STACK_OK, populateAcl(&acl, 1));
- SetPersistentHandler(&ps, true);
+ //GET CBOR POST payload
+ size_t size = 0;
+ uint8_t *payload = NULL;
+ EXPECT_EQ(OC_STACK_OK, AclToCBORPayload(&acl, &payload, &size));
+ ASSERT_TRUE(NULL != payload);
- //Populate ACL
- VERIFY_SUCCESS(TAG, (OC_STACK_OK == populateAcl(&acl, 1)), ERROR);
+ // Security Payload
+ OCSecurityPayload *securityPayload = OCSecurityPayloadCreate(payload, size);
+ ASSERT_TRUE(NULL != securityPayload);
- //GET json POST payload
- jsonStr = BinToAclJSON(&acl);
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+ static OCPersistentStorage ps = OCPersistentStorage();
+ SetPersistentHandler(&ps, true);
//Create Entity Handler POST request payload
+ OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
ehReq.method = OC_REST_POST;
- ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
- ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_ERROR == ehRet);
+ ehReq.payload = (OCPayload *)securityPayload;
+ ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
//Create Entity Handler GET request wit query
- ehReq.method = OC_REST_GET;
+ ehReq.method = OC_REST_GET;
+ char query[] = "subjectuuid=2222222222222222;resources=/a/led";
ehReq.query = (char*)OICMalloc(strlen(query)+1);
- VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
+ ASSERT_TRUE(NULL != ehReq.query);
OICStrcpy(ehReq.query, strlen(query)+1, query);
- ehRet = ACLEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_OK == ehRet);
+ ACLEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
-exit:
// Perform cleanup
- OCPayloadDestroy(ehReq.payload);
+ OCPayloadDestroy((OCPayload *)securityPayload);
+ DeInitACLResource();
OICFree(ehReq.query);
- OICFree(jsonStr);
+ OICFree(payload);
}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "gtest/gtest.h"
+#include "cainterface.h"
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "payload_logging.h"
+#include "psinterface.h"
+#include "secureresourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "srmutility.h"
+#include "amaclresource.h"
+#include "security_internals.h"
+
+using namespace std;
+
+#define TAG "SRM-AMACL-UT"
+
+TEST(AMACLResourceTest, CBORAMACLConversion)
+{
+ OicSecAmacl_t *secAmacl = (OicSecAmacl_t *) OICCalloc(1, sizeof(*secAmacl));
+ ASSERT_TRUE(NULL != secAmacl);
+ uint8_t amss[] = {0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35};
+ uint8_t amss1[] = {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36};
+ secAmacl->amssLen = 2;
+ secAmacl->amss = (OicUuid_t *)OICCalloc(secAmacl->amssLen, sizeof(*secAmacl->amss));
+ if (!secAmacl->amss)
+ {
+ DeleteAmaclList(secAmacl);
+ }
+ ASSERT_TRUE(NULL != secAmacl->amss);
+ memcpy(secAmacl->amss[0].id, amss, sizeof(amss));
+ memcpy(secAmacl->amss[1].id, amss1, sizeof(amss1));
+
+ const char *rsrc[] = { "/a/led", "/a/fan"};
+ secAmacl->resourcesLen = 2;
+ secAmacl->resources = (char **)OICCalloc(secAmacl->resourcesLen,
+ sizeof(*secAmacl->resources));
+ if (!secAmacl->resources)
+ {
+ DeleteAmaclList(secAmacl);
+ }
+ ASSERT_TRUE(NULL != secAmacl->resources);
+ for (size_t i = 0 ; i < secAmacl->resourcesLen; i++)
+ {
+ secAmacl->resources[i] = OICStrdup(rsrc[i]);
+ ASSERT_TRUE(NULL != secAmacl->resources[i]);
+ }
+ uint8_t ownrs[] = {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
+ 0x32, 0x32, 0x32, 0x32, 0x32, 0x32};
+ memcpy(secAmacl->rownerID.id, ownrs, sizeof(ownrs));
+
+ OicSecAmacl_t *secAmacl1 = (OicSecAmacl_t *) OICCalloc(1, sizeof(*secAmacl1));
+ if (!secAmacl1)
+ {
+ DeleteAmaclList(secAmacl);
+ }
+ ASSERT_TRUE(NULL != secAmacl1);
+ secAmacl1->amssLen = 2;
+ secAmacl1->amss = (OicUuid_t *)OICCalloc(2, sizeof(*secAmacl1->amss));
+ if (!secAmacl1->amss)
+ {
+ DeleteAmaclList(secAmacl);
+ DeleteAmaclList(secAmacl1);
+ }
+ ASSERT_TRUE(NULL != secAmacl1->amss);
+ memcpy(secAmacl1->amss[0].id, amss, sizeof(amss));
+ memcpy(secAmacl1->amss[1].id, amss1, sizeof(amss1));
+
+ const char *rsrc1[] = { "/b/led", "/b/fan"};
+ secAmacl1->resourcesLen = 2;
+ secAmacl1->resources = (char **)OICCalloc(secAmacl1->resourcesLen,
+ sizeof(*secAmacl1->resources));
+ if (!secAmacl1->resources)
+ {
+ DeleteAmaclList(secAmacl);
+ DeleteAmaclList(secAmacl1);
+ }
+ ASSERT_TRUE(NULL != secAmacl1->resources);
+ for (size_t i = 0 ; i < secAmacl1->resourcesLen; i++)
+ {
+ secAmacl1->resources[i] = OICStrdup(rsrc1[i]);
+ ASSERT_TRUE(NULL != secAmacl1->resources[i]);
+ }
+ memcpy(secAmacl1->rownerID.id, ownrs, sizeof(ownrs));
+ secAmacl1->next = NULL;
+ secAmacl->next = secAmacl1;
+
+ size_t size = 0;
+ uint8_t *psStorage = NULL;
+ EXPECT_EQ(OC_STACK_OK, AmaclToCBORPayload(secAmacl, &psStorage, &size));
+ if (!psStorage)
+ {
+ DeleteAmaclList(secAmacl);
+ }
+ ASSERT_TRUE(NULL != psStorage);
+
+ OicSecAmacl_t *amacl = NULL;
+ EXPECT_EQ(OC_STACK_OK, CBORPayloadToAmacl(psStorage, size, &amacl));
+ if (!amacl)
+ {
+ DeleteAmaclList(secAmacl);
+ OICFree(psStorage);
+ }
+ ASSERT_TRUE(NULL != amacl);
+
+ EXPECT_EQ(secAmacl->amssLen, amacl->amssLen);
+ EXPECT_EQ(sizeof(secAmacl->amss[0].id), sizeof(amacl->amss[0].id));
+ EXPECT_EQ(sizeof(secAmacl->amss[1].id), sizeof(amacl->amss[1].id));
+ EXPECT_STREQ(secAmacl->resources[0], amacl->resources[0]);
+ EXPECT_STREQ(secAmacl->resources[1], amacl->resources[1]);
+ EXPECT_EQ(secAmacl->resourcesLen, amacl->resourcesLen);
+ EXPECT_EQ(memcmp(secAmacl->rownerID.id, amacl->rownerID.id, sizeof(amacl->rownerID.id)), 0);
+
+ DeleteAmaclList(secAmacl);
+ DeleteAmaclList(amacl);
+ OICFree(psStorage);
+}
+//******************************************************************
+//
// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "gtest/gtest.h"
-#include "ocstack.h"
+#include "logger.h"
#include "ocpayload.h"
-#include "resourcemanager.h"
-#include "securevirtualresourcetypes.h"
-#include "credresource.h"
+#include "ocstack.h"
#include "oic_malloc.h"
#include "oic_string.h"
+#include "resourcemanager.h"
+#include "credresource.h"
+#include "securevirtualresourcetypes.h"
#include "srmtestcommon.h"
#include "srmutility.h"
-#include "logger.h"
+#include "psinterface.h"
+#include "security_internals.h"
#define TAG "SRM-CRED-UT"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//Declare Cred resource methods for testing
-OCStackResult CreateCredResource();
-OCEntityHandlerResult CredEntityHandler (OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest);
-char * BinToCredJSON(const OicSecCred_t * pstat);
-OicSecCred_t * JSONToCredBin(const char * jsonStr);
-void InitSecCredInstance(OicSecCred_t * cred);
-void DeleteCredList(OicSecCred_t* cred);
-const OicSecCred_t* GetCredResourceData(const OicUuid_t* subject);
-
-#ifdef __cplusplus
-}
-#endif
-
-
OicSecCred_t * getCredList()
{
-
- OicSecCred_t * cred = NULL;
size_t sz = 0;
-
- cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+ OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
VERIFY_NON_NULL(TAG, cred, ERROR);
cred->credId = 1234;
- OICStrcpy((char *)cred->subject.id, sizeof(cred->subject.id), "subject1");
+ // use |memcpy| for copying full-lengthed UUID without null termination
+ memcpy(cred->subject.id, "1111111111111111", sizeof(cred->subject.id));
#if 0
cred->roleIdsLen = 2;
VERIFY_NON_NULL(TAG, cred->roleIds, ERROR);
OICStrcpy((char *)cred->roleIds[0].id, sizeof(cred->roleIds[0].id), "role11");
OICStrcpy((char *)cred->roleIds[1].id, sizeof(cred->roleIds[1].id), "role12");
-
#endif
cred->credType = SYMMETRIC_PAIR_WISE_KEY;
- cred->privateData.data = (char *)OICCalloc(1, strlen("My private Key11") + 1);
+ cred->privateData.data = (uint8_t *)OICCalloc(1, strlen("My private Key11") + 1);
VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
- OICStrcpy(cred->privateData.data, strlen("My private Key11")+1,"My private Key11");
- cred->ownersLen = 1;
- cred->owners = (OicUuid_t*)OICCalloc(cred->ownersLen, sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, cred->owners, ERROR);
- OICStrcpy((char *)cred->owners[0].id, sizeof(cred->owners[0].id), "ownersId11");
-
- cred->next = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+ OICStrcpy((char *)cred->privateData.data, strlen("My private Key11")+1,"My private Key11");
+ // use |memcpy| for copying full-lengthed UUID without null termination
+ memcpy(cred->rownerID.id, "aaaaaaaaaaaaaaaa", sizeof(cred->rownerID.id));
+ cred->next = (OicSecCred_t*)OICCalloc(1, sizeof(*cred->next));
VERIFY_NON_NULL(TAG, cred->next, ERROR);
cred->next->credId = 5678;
- OICStrcpy((char *)cred->next->subject.id, sizeof(cred->next->subject.id), "subject2");
+ // use |memcpy| for copying full-lengthed UUID without null termination
+ memcpy(cred->next->subject.id, "2222222222222222", sizeof(cred->next->subject.id));
#if 0
cred->next->roleIdsLen = 0;
#endif
cred->next->credType = SYMMETRIC_PAIR_WISE_KEY;
sz = strlen("My private Key21") + 1;
- cred->next->privateData.data = (char *)OICCalloc(1, sz);
+ cred->next->privateData.data = (uint8_t *)OICCalloc(1, sz);
VERIFY_NON_NULL(TAG, cred->next->privateData.data, ERROR);
- OICStrcpy(cred->next->privateData.data, sz,"My private Key21");
+ OICStrcpy((char *)cred->next->privateData.data, sz, "My private Key21");
#if 0
- sz = strlen("My Public Key123") + 1
+ sz = strlen("My Public Key123") + 1;
cred->next->publicData.data = (char *)OICCalloc(1, sz);
VERIFY_NON_NULL(TAG, cred->next->publicData.data, ERROR);
OICStrcpy(cred->next->publicData.data, sz,"My Public Key123");
#endif
- cred->next->ownersLen = 2;
- cred->next->owners = (OicUuid_t*)OICCalloc(cred->next->ownersLen, sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, cred->next->owners, ERROR);
- OICStrcpy((char *)cred->next->owners[0].id, sizeof(cred->next->owners[0].id), "ownersId21");
- OICStrcpy((char *)cred->next->owners[1].id, sizeof(cred->next->owners[1].id), "ownersId22");
+ // use |memcpy| for copying full-lengthed UUID without null termination
+ memcpy(cred->next->rownerID.id, "bbbbbbbbbbbbbbbb", sizeof(cred->next->rownerID.id));
return cred;
EXPECT_TRUE(NULL != cred);
const OicSecCred_t *credTmp1 = NULL;
- for(credTmp1 = cred; credTmp1; credTmp1 = credTmp1->next)
+ for (credTmp1 = cred; credTmp1; credTmp1 = credTmp1->next)
{
OIC_LOG_V(INFO, TAG, "\ncred->credId = %d", credTmp1->credId);
OIC_LOG_V(INFO, TAG, "cred->subject.id = %s", credTmp1->subject.id);
{
OIC_LOG_V(INFO, TAG, "cred->privateData.data = %s", credTmp1->privateData.data);
}
+#ifdef __WITH_X509__
if(credTmp1->publicData.data)
{
OIC_LOG_V(INFO, TAG, "cred->publicData.data = %s", credTmp1->publicData.data);
}
- OIC_LOG_V(INFO, TAG, "cred->ownersLen = %zu", credTmp1->ownersLen);
- for(size_t i = 0; i < cred->ownersLen; i++)
- {
- OIC_LOG_V(INFO, TAG, "cred->owners[%zu].id = %s", i, credTmp1->owners[i].id);
- }
+#endif /* __WITH_X509__ */
+ OIC_LOG_V(INFO, TAG, "cred->rownerID = %s", credTmp1->rownerID.id);
}
}
//InitCredResource Tests
-TEST(InitCredResourceTest, InitCredResource)
+TEST(CredResourceTest, InitCredResource)
{
EXPECT_EQ(OC_STACK_INVALID_PARAM, InitCredResource());
}
//DeInitCredResource Tests
-TEST(DeInitCredResourceTest, DeInitCredResource)
+TEST(CredResourceTest, DeInitCredResource)
{
EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitCredResource());
}
//CreateCredResource Tests
-TEST(CreateCredResourceTest, CreateCredResource)
+TEST(CredResourceTest, CreateCredResource)
{
EXPECT_EQ(OC_STACK_INVALID_PARAM, CreateCredResource());
}
//CredEntityHandler Tests
-TEST(CredEntityHandlerTest, CredEntityHandlerWithDummyRequest)
+TEST(CredResourceTest, CredEntityHandlerWithDummyRequest)
{
- OCEntityHandlerRequest req;
+ OCEntityHandlerRequest req = OCEntityHandlerRequest();
EXPECT_EQ(OC_EH_ERROR,
- CredEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+ CredEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req, NULL));
}
-TEST(CredEntityHandlerTest, CredEntityHandlerWithNULLRequest)
+TEST(CredResourceTest, CredEntityHandlerWithNULLRequest)
{
EXPECT_EQ(OC_EH_ERROR,
- CredEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, NULL));
+ CredEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, NULL, NULL));
}
-TEST(CredEntityHandlerTest, CredEntityHandlerInvalidFlag)
+TEST(CredResourceTest, CredEntityHandlerInvalidFlag)
{
- OCEntityHandlerRequest req;
+ OCEntityHandlerRequest req = OCEntityHandlerRequest();
EXPECT_EQ(OC_EH_ERROR,
- CredEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, &req));
+ CredEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, &req, NULL));
}
//Cred DELETE request
-TEST(CredEntityHandlerTest, CredEntityHandlerDeleteTest)
+TEST(CredResourceTest, CredEntityHandlerDeleteTest)
{
OCEntityHandlerRequest ehReq = OCEntityHandlerRequest();
static OCPersistentStorage ps = OCPersistentStorage();
const OicSecCred_t* subjectCred1 = NULL;
const OicSecCred_t* subjectCred2 = NULL;
- char *jsonStr = NULL;
OCEntityHandlerResult ehRet = OC_EH_ERROR;
- char query[] = "sub=c3ViamVjdDE=";
+ char query[] = "subjectuuid=31313131-3131-3131-3131-313131313131"; //canonical uuid of subject1
SetPersistentHandler(&ps, true);
OicSecCred_t *cred = getCredList();
- VERIFY_NON_NULL(TAG, cred, ERROR);
-
- jsonStr = BinToCredJSON(cred);
- VERIFY_NON_NULL(TAG, jsonStr, ERROR);
+ ASSERT_TRUE(NULL != cred);
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred, &payload, &size));
+ if (!payload)
+ {
+ DeleteCredList(cred);
+ }
+ ASSERT_TRUE(NULL != payload);
// Create Entity Handler POST request payload
ehReq.method = OC_REST_POST;
- ehReq.payload = (OCPayload*)OCSecurityPayloadCreate(jsonStr);
- ehRet = CredEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_ERROR == ehRet);
+ ehReq.payload = (OCPayload *)OCSecurityPayloadCreate(payload, size);
+ if (!ehReq.payload)
+ {
+ OICFree(payload);
+ DeleteCredList(cred);
+ }
+ ASSERT_TRUE( NULL != ehReq.payload);
+ EXPECT_EQ(OC_EH_ERROR, CredEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL));
// Verify if SRM contains Credential for the subject
subjectCred1 = GetCredResourceData(&cred->subject);
EXPECT_TRUE(NULL != subjectCred1);
- // Create Entity Handler DELETE request
- ehReq.method = OC_REST_DELETE;
- ehReq.query = (char*)OICMalloc(strlen(query)+1);
- VERIFY_NON_NULL(TAG, ehReq.query, ERROR);
- OICStrcpy(ehReq.query, strlen(query)+1, query);
+ // Create Entity Handler DELETE request
+ ehReq.method = OC_REST_DELETE;
+ ehReq.query = (char *)OICCalloc(1, strlen(query)+1);
+ if (!ehReq.query)
+ {
+ OICFree(payload);
+ DeleteCredList(cred);
+ }
+ ASSERT_TRUE(NULL != ehReq.query);
+ OICStrcpy(ehReq.query, strlen(query)+1, query);
- ehRet = CredEntityHandler(OC_REQUEST_FLAG, &ehReq);
- EXPECT_TRUE(OC_EH_ERROR == ehRet);
+ ehRet = CredEntityHandler(OC_REQUEST_FLAG, &ehReq, NULL);
+ EXPECT_EQ(OC_EH_ERROR, ehRet);
- // Verify if SRM has deleted ACE for the subject
- subjectCred2 = GetCredResourceData(&cred->subject);
- EXPECT_TRUE(NULL == subjectCred2);
+ // Verify if SRM has deleted ACE for the subject
+ subjectCred2 = GetCredResourceData(&cred->subject);
+ EXPECT_TRUE(NULL == subjectCred2);
-exit:
- // Perform cleanup
- OICFree(ehReq.query);
- OICFree(jsonStr);
- OCPayloadDestroy(ehReq.payload);
- if(NULL != cred)
- {
- DeInitCredResource();
- DeleteCredList(cred);
- }
+ // Perform cleanup
+ OICFree(ehReq.query);
+ OICFree(payload);
+ DeInitCredResource();
+ DeleteCredList(cred);
+ OCPayloadDestroy((OCPayload *)ehReq.payload);
}
-//BinToCredJSON Tests
-TEST(BinToCredJSONTest, BinToCredJSONNullCred)
+TEST(CredResourceTest, CredToCBORPayloadNULL)
{
- char* value = BinToCredJSON(NULL);
- EXPECT_TRUE(value == NULL);
+ OicSecCred_t *cred = getCredList();
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(NULL, NULL, 0));
+ size_t size = 0;
+ uint8_t *cborPayload = (uint8_t *) OICCalloc(1, 10);
+ if (!cborPayload)
+ {
+ DeleteCredList(cred);
+ }
+ ASSERT_TRUE(NULL != cborPayload);
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, &cborPayload, &size));
+ OICFree(cborPayload);
+ cborPayload = NULL;
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(NULL, &cborPayload, &size));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, &cborPayload, 0));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CredToCBORPayload(cred, NULL, &size));
+ DeleteCredList(cred);
}
-TEST(BinToCredJSONTest, BinToCredJSONValidCred)
+TEST(CredResourceTest, CredToCBORPayloadVALID)
{
- char* json = NULL;
- OicSecCred_t * cred = getCredList();
+ uint8_t* payload = NULL;
+ size_t size = 0;
+ OicSecCred_t *cred = getCredList();
- json = BinToCredJSON(cred);
+ EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred, &payload, &size));
+ if (!payload)
+ {
+ DeleteCredList(cred);
+ }
+ ASSERT_TRUE(NULL != payload);
- OIC_LOG_V(INFO, TAG, "BinToCredJSON:%s\n", json);
- EXPECT_TRUE(json != NULL);
DeleteCredList(cred);
- OICFree(json);
+ OICFree(payload);
}
-//JSONToCredBin Tests
-TEST(JSONToCredBinTest, JSONToCredBinValidJSON)
+TEST(CredResourceTest, CBORPayloadToCredVALID)
{
- OicSecCred_t* cred1 = getCredList();
- char* json = BinToCredJSON(cred1);
+ OicSecCred_t *cred1 = getCredList();
- EXPECT_TRUE(json != NULL);
- OicSecCred_t *cred2 = JSONToCredBin(json);
- EXPECT_TRUE(cred2 != NULL);
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ EXPECT_EQ(OC_STACK_OK, CredToCBORPayload(cred1, &payload, &size));
DeleteCredList(cred1);
+ ASSERT_TRUE(NULL != payload);
+
+ OicSecCred_t *cred2 = NULL;
+ EXPECT_EQ(OC_STACK_OK, CBORPayloadToCred(payload, size, &cred2));
+ OICFree(payload);
+ ASSERT_TRUE(cred2 != NULL);
DeleteCredList(cred2);
- OICFree(json);
}
-TEST(JSONToCredBinTest, JSONToCredBinNullJSON)
+TEST(CredResourceTest, CBORPayloadToCredNULL)
{
- OicSecCred_t *cred = JSONToCredBin(NULL);
- EXPECT_TRUE(cred == NULL);
+ OicSecCred_t *cred = NULL;
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToCred(NULL, 0, NULL));
+ uint8_t *cborPayload = (uint8_t *) OICCalloc(1, 10);
+ ASSERT_TRUE(NULL != cborPayload);
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToCred(NULL, 0, &cred));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToCred(cborPayload, 0, NULL));
+ cred = getCredList();
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToCred(cborPayload, 0, &cred));
+ DeleteCredList(cred);
+ OICFree(cborPayload);
}
//GetCredResourceData Test
-TEST(CredGetResourceDataTest, GetCredResourceDataNULLSubject)
+TEST(CredResourceTest, GetCredResourceDataNULLSubject)
{
- EXPECT_TRUE(NULL == GetCredResourceData(NULL));
+ EXPECT_EQ(NULL, GetCredResourceData(NULL));
}
-TEST(CredGenerateCredentialTest, GenerateCredentialValidInput)
+TEST(CredResourceTest, GenerateCredentialValidInput)
{
- OicUuid_t owners[1];
- OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId21");
+ OicUuid_t rownerID = {{0}};
+ OICStrcpy((char *)rownerID.id, sizeof(rownerID.id), "ownersId21");
OicUuid_t subject = {{0}};
OICStrcpy((char *)subject.id, sizeof(subject.id), "subject11");
- char privateKey[] = "My private Key11";
+ uint8_t privateKey[] = "My private Key11";
+ OicSecKey_t key = {privateKey, sizeof(privateKey)};
OicSecCred_t * cred = NULL;
-
cred = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
- privateKey, 1, owners);
+ &key, &rownerID);
printCred(cred);
- EXPECT_TRUE(NULL != cred);
+ ASSERT_TRUE(NULL != cred);
DeleteCredList(cred);
}
-TEST(GenerateAndAddCredentialTest, GenerateAndAddCredentialValidInput)
+TEST(CredResourceTest, GenerateAndAddCredentialValidInput)
{
- OicUuid_t owners[1];
- OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId11");
+ OicUuid_t rownerID = {{0}};
+ OICStrcpy((char *)rownerID.id, sizeof(rownerID.id), "ownersId11");
OicUuid_t subject = {{0}};
OICStrcpy((char *)subject.id, sizeof(subject.id), "subject11");
- char privateKey[] = "My private Key11";
+ uint8_t privateKey[] = "My private Key11";
+ OicSecKey_t key = {privateKey, sizeof(privateKey)};
- OicSecCred_t * cred1 = NULL;
- OicSecCred_t * headCred = NULL;
+ OicSecCred_t *cred1 = NULL;
+ OicSecCred_t *headCred = NULL;
cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
- privateKey, 1, owners);
+ &key, &rownerID);
- EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+ EXPECT_EQ(OC_STACK_OK, AddCredential(cred1));
headCred = cred1;
- OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId22");
+ OICStrcpy((char *)rownerID.id, sizeof(rownerID.id), "ownersId22");
OICStrcpy((char *)subject.id, sizeof(subject.id), "subject22");
cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
- privateKey, 1, owners);
- EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+ &key, &rownerID);
+ EXPECT_EQ(OC_STACK_OK, AddCredential(cred1));
- OICStrcpy((char *)owners[0].id, sizeof(owners[0].id), "ownersId33");
+ OICStrcpy((char *)rownerID.id, sizeof(rownerID.id), "ownersId33");
OICStrcpy((char *)subject.id, sizeof(subject.id), "subject33");
cred1 = GenerateCredential(&subject, SYMMETRIC_PAIR_WISE_KEY, NULL,
- privateKey, 1, owners);
- EXPECT_EQ(OC_STACK_ERROR, AddCredential(cred1));
+ &key, &rownerID);
+ EXPECT_EQ(OC_STACK_OK, AddCredential(cred1));
const OicSecCred_t* credList = GetCredResourceData(&headCred->subject);
printCred(credList);
DeleteCredList(headCred);
-
}
#if 0
EXPECT_TRUE(NULL != GetCredResourceData(cred->subject));
}
#endif
-
-
+//******************************************************************
+//
// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "gtest/gtest.h"
#include "ocstack.h"
+#include "ocserverrequest.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
#include "resourcemanager.h"
#include "securevirtualresourcetypes.h"
#include "srmresourcestrings.h"
#include "doxmresource.h"
-#include "ocserverrequest.h"
-#include "oic_string.h"
-#include "oic_malloc.h"
-#include "logger.h"
+#include "security_internals.h"
#define TAG "SRM-DOXM"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-//Declare Doxm resource methods for testing
-OCStackResult CreateDoxmResource();
-OCEntityHandlerResult DoxmEntityHandler (OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest);
-char * BinToDoxmJSON(const OicSecDoxm_t * doxm);
-OicSecDoxm_t * JSONToDoxmBin(const char * jsonStr);
-void InitSecDoxmInstance(OicSecDoxm_t * doxm);
-OCEntityHandlerResult HandleDoxmPostRequest (const OCEntityHandlerRequest * ehRequest);
-void DeleteDoxmBinData(OicSecDoxm_t* doxm);
-OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest * ehRequest);
-#ifdef __cplusplus
-}
-#endif
-
-
OicSecDoxm_t * getBinDoxm()
{
- OicSecDoxm_t * doxm = (OicSecDoxm_t*)OICCalloc(1, sizeof(OicSecDoxm_t));
- if(!doxm)
+ OicSecDoxm_t *doxm = (OicSecDoxm_t *)OICCalloc(1, sizeof(*doxm));
+ if (!doxm)
{
return NULL;
}
doxm->oxmTypeLen = 1;
- doxm->oxmType = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(char *));
- if(!doxm->oxmType)
+ doxm->oxmType = (OicUrn_t *)OICCalloc(doxm->oxmTypeLen, sizeof(*doxm->oxmType));
+ if (!doxm->oxmType)
{
OICFree(doxm);
return NULL;
}
- doxm->oxmType[0] = (char*)OICMalloc(strlen(OXM_JUST_WORKS) + 1);
- if(!doxm->oxmType[0])
+ doxm->oxmType[0] = (char *) OICMalloc(strlen(OXM_JUST_WORKS) + 1);
+ if (!doxm->oxmType[0])
{
OICFree(doxm->oxmType);
OICFree(doxm);
doxm->owned = true;
//TODO: Need more clarification on deviceIDFormat field type.
//doxm.deviceIDFormat = URN;
- OICStrcpy((char *) doxm->deviceID.id, strlen("deviceId") + 1, "deviceId");
- OICStrcpy((char *) doxm->owner.id, strlen("ownersId") + 1, "ownersId");
+
+ uint8_t deviceId[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64};
+ memcpy(doxm->deviceID.id, deviceId, sizeof(deviceId));
+ uint8_t ownerId[] = {0x6f, 0x77, 0x6e, 0x65, 0x72, 0x73, 0x49, 0x64};
+ memcpy(doxm->owner.id, ownerId, sizeof(ownerId));
return doxm;
}
//InitDoxmResource Tests
-TEST(InitDoxmResourceTest, InitDoxmResource)
+TEST(DoxmResourceTest, InitDoxmResource)
{
EXPECT_EQ(OC_STACK_INVALID_PARAM, InitDoxmResource());
}
//DeInitDoxmResource Tests
-TEST(DeInitDoxmResourceTest, DeInitDoxmResource)
+TEST(DoxmResourceTest, DeInitDoxmResource)
{
EXPECT_EQ(OC_STACK_ERROR, DeInitDoxmResource());
}
//CreateDoxmResource Tests
-TEST(CreateDoxmResourceTest, CreateDoxmResource)
+TEST(DoxmResourceTest, CreateDoxmResource)
{
EXPECT_EQ(OC_STACK_INVALID_PARAM, CreateDoxmResource());
}
//DoxmEntityHandler Tests
-TEST(DoxmEntityHandlerTest, DoxmEntityHandlerWithDummyRequest)
+TEST(DoxmResourceTest, DoxmEntityHandlerWithDummyRequest)
{
- OCEntityHandlerRequest req;
- EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+ OCEntityHandlerRequest req = OCEntityHandlerRequest();
+ EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req, NULL));
}
-TEST(DoxmEntityHandlerTest, DoxmEntityHandlerWithNULLRequest)
+TEST(DoxmResourceTest, DoxmEntityHandlerWithNULLRequest)
{
- EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, NULL));
+ EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, NULL, NULL));
}
-TEST(DoxmEntityHandlerTest, DoxmEntityHandlerInvalidFlag)
+TEST(DoxmResourceTest, DoxmEntityHandlerInvalidFlag)
{
- OCEntityHandlerRequest req;
- EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, &req));
+ OCEntityHandlerRequest req = OCEntityHandlerRequest();
+ EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, &req, NULL));
}
-TEST(DoxmEntityHandlerTest, DoxmEntityHandlerValidRequest)
+TEST(DoxmResourceTest, DoxmEntityHandlerValidRequest)
{
EXPECT_EQ(OC_STACK_INVALID_PARAM, InitDoxmResource());
char query[] = "oxm=0;owned=false;owner=owner1";
OCEntityHandlerRequest req = OCEntityHandlerRequest();
req.method = OC_REST_GET;
req.query = OICStrdup(query);
- EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+ EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req, NULL));
OICFree(req.query);
}
-TEST(DoxmEntityHandlerTest, DoxmEntityHandlerDeviceIdQuery)
+TEST(DoxmResourceTest, DoxmEntityHandlerDeviceIdQuery)
{
EXPECT_EQ(OC_STACK_INVALID_PARAM, InitDoxmResource());
- char query[] = "deviceid=MjIyMjIyMjIyMjIyMjIyMg==";
+ char query[] = "deviceuuid=2222222222222222";
OCEntityHandlerRequest req = OCEntityHandlerRequest();
req.method = OC_REST_GET;
req.query = OICStrdup(query);
- EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+ EXPECT_EQ(OC_EH_ERROR, DoxmEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req, NULL));
OICFree(req.query);
}
-//BinToDoxmJSON Tests
-TEST(BinToDoxmJSONTest, BinToDoxmJSONNullDoxm)
+TEST(DoxmResourceTest, DoxmToCBORPayloadNULL)
{
- char* value = BinToDoxmJSON(NULL);
- EXPECT_TRUE(value == NULL);
+ OicSecDoxm_t *doxm = getBinDoxm();
+ size_t size = 10;
+ uint8_t *payload = NULL;
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, DoxmToCBORPayload(NULL, NULL, 0));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, DoxmToCBORPayload(doxm, NULL, &size));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, DoxmToCBORPayload(doxm, &payload, 0));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, DoxmToCBORPayload(NULL, &payload, &size));
+ DeleteDoxmBinData(doxm);
}
-TEST(BinToDoxmJSONTest, BinToDoxmJSONValidDoxm)
+TEST(DoxmResourceTest, DoxmToCBORPayloadVALID)
{
- OicSecDoxm_t * doxm = getBinDoxm();
+ OicSecDoxm_t *doxm = getBinDoxm();
- char * json = BinToDoxmJSON(doxm);
- OIC_LOG_V(INFO, TAG, "BinToDoxmJSON:%s", json);
- EXPECT_TRUE(json != NULL);
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ EXPECT_EQ(OC_STACK_OK, DoxmToCBORPayload(doxm, &payload, &size));
+ EXPECT_TRUE(payload != NULL);
DeleteDoxmBinData(doxm);
- OICFree(json);
+ OICFree(payload);
}
-//JSONToDoxmBin Tests
-TEST(JSONToDoxmBinTest, JSONToDoxmBinValidJSON)
+//CBORPayloadToDoxm Tests
+TEST(DoxmResourceTest, CBORPayloadToDoxmNULL)
{
- OicSecDoxm_t * doxm1 = getBinDoxm();
- char * json = BinToDoxmJSON(doxm1);
- EXPECT_TRUE(json != NULL);
-
- OicSecDoxm_t *doxm2 = JSONToDoxmBin(json);
- EXPECT_TRUE(doxm2 != NULL);
-
- DeleteDoxmBinData(doxm1);
- DeleteDoxmBinData(doxm2);
- OICFree(json);
+ OicSecDoxm_t *doxm = NULL;
+ uint8_t *cborPayload = (uint8_t *)OICCalloc(1, sizeof(uint8_t));
+ size_t size = 10;
+ ASSERT_TRUE(NULL != cborPayload);
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToDoxm(NULL, 0, NULL));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToDoxm(NULL, size, &doxm));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToDoxm(cborPayload, size, NULL));
+ OICFree(cborPayload);
}
-TEST(JSONToDoxmBinTest, JSONToDoxmBinNullJSON)
+TEST(DoxmResourceTest, CBORPayloadToDoxmVALID)
{
- OicSecDoxm_t *doxm = JSONToDoxmBin(NULL);
- EXPECT_TRUE(doxm == NULL);
+ OicSecDoxm_t *doxm = getBinDoxm();
+ uint8_t *payload = NULL;
+ size_t size = 0;
+ EXPECT_EQ(OC_STACK_OK, DoxmToCBORPayload(doxm, &payload, &size));
+ EXPECT_TRUE(payload != NULL);
+
+ OicSecDoxm_t *doxmSec = NULL;
+ EXPECT_EQ(OC_STACK_OK, CBORPayloadToDoxm(payload, size, &doxmSec));
+ ASSERT_TRUE(doxmSec != NULL);
+ EXPECT_EQ(doxmSec->oxmTypeLen, doxm->oxmTypeLen);
+ EXPECT_STREQ(doxmSec->oxmType[0], doxm->oxmType[0]);
+ EXPECT_EQ(doxmSec->oxmLen, doxm->oxmLen);
+ EXPECT_EQ(doxmSec->oxm[0], doxm->oxm[0]);
+ EXPECT_EQ(doxmSec->oxmSel, doxm->oxmSel);
+ EXPECT_EQ(doxmSec->sct, doxm->sct);
+ EXPECT_EQ(doxmSec->owned, doxm->owned);
+
+ DeleteDoxmBinData(doxmSec);
+ DeleteDoxmBinData(doxm);
+ OICFree(payload);
}
#if 0
{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad"
- ],
- "perms": 2,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl"
- ],
- "perms": 6,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- }
- ],
- "pstat": {
- "isop": false,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": false,
- "deviceid": "MjIyMjIyMjIyMjIyMjIyMg=="
- }
-}
+ "acl": {
+ "aclist": {
+ "aces": [
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/res",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/p",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/res/types/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/ad",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 2
+ },
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/sec/doxm",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/pstat",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/acl",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 6
+ },
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/sec/pconf",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/dpairing",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 6
+ }
+ ]
+ },
+ "rowneruuid" : "756E6B6E-6F77-6564-4465-766963654964"
+ },
+ "pstat": {
+ "isop": false,
+ "deviceuuid": "756E6B6E-6F77-6564-4465-766963654964",
+ "rowneruuid": "756E6B6E-6F77-6564-4465-766963654964",
+ "cm": 2,
+ "tm": 0,
+ "om": 3,
+ "sm": 3
+ },
+ "doxm": {
+ "oxms": [0],
+ "oxmsel": 0,
+ "sct": 1,
+ "owned": false,
+ "deviceuuid": "756E6B6E-6F77-6564-4465-766963654964",
+ "devowneruuid": "",
+ "rowneruuid": "756E6B6E-6F77-6564-4465-766963654964",
+ "dpc": true
+ }
+}
\ No newline at end of file
{
- "acl": [
- {
- "sub": "MTExMTExMTExMTExMTExMQ==",
- "rsrc": [
- "/oic/light",
- "/oic/fan"
- ],
- "perms": 255,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- },
- {
- "sub": "MzMzMzMzMzMzMzMzMzMzMw==",
- "rsrc": [
- "/oic/light",
- "/oic/garage"
- ],
- "perms": 255,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg==",
- "NDQ0NDQ0NDQ0NDQ0NDQ0NA=="
- ]
- }
- ],
-
- "pstat": {
- "isop": false,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 1234,
- "cm": 63,
- "tm": 48,
- "om": 0,
- "sm": [3, 1]
- },
-
- "amacl": [
- {
- "rsrc": ["/a/led", "/a/fan"],
- "amss": [
- "NTU1NTU1NTU1NTU1NTU1NQ==",
- "NjY2NjY2NjY2NjY2NjY2Ng=="
- ],
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- },
- {
- "rsrc": ["/b/led", "/b/fan"],
- "amss": [
- "NTU1NTU1NTU1NTU1NTU1NQ==",
- "NjY2NjY2NjY2NjY2NjY2Ng=="
- ],
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- }
- ],
-
-"svc": [
- {
- "svcdid": "NTU1NTU1NTU1NTU1NTU1NQ==",
- "svct": 1,
- "ownrs" : [
- "OTk5OTk5OTk5OTk5OTk5OQ=="
- ]
- },
- {
- "svcdid": "NjY2NjY2NjY2NjY2NjY2Ng==",
- "svct": 1,
- "ownrs" : [
- "OTk5OTk5OTk5OTk5OTk5OQ=="
- ]
- }
- ]
+ "acl": {
+ "aclist": {
+ "aces": [
+ {
+ "subjectuuid": "31313131-3131-3131-3131-313131313131",
+ "resources": [
+ {
+ "href": "/oic/light",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/fan",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 31
+ },
+ {
+ "subjectuuid": "33333333-3333-3333-3333-333333333333",
+ "resources": [
+ {
+ "href": "/oic/light",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/garage",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 31
+ }
+ ]
+ },
+ "rowneruuid" : "32323232-3232-3232-3232-323232323232"
+ },
+ "pstat": {
+ "isop": false,
+ "deviceuuid": "756E6B6E-6F77-6564-4465-766963654964",
+ "rowneruuid": "756E6B6E-6F77-6564-4465-766963654964",
+ "cm": 63,
+ "tm": 48,
+ "om": 0,
+ "sm": 3
+ }
}
--- /dev/null
+¿caclY\ 2\8b¢faclist¡daces\84£ksubjectuuida*iresources\86¤dhrefh/oic/rescrel`brt`bif`¤dhreff/oic/dcrel`brt`bif`¤dhreff/oic/pcrel`brt`bif`¤dhrefp/oic/res/types/dcrel`brt`bif`¤dhrefg/oic/adcrel`brt`bif`¤dhrefl/oic/sec/aclcrel`brt`bif`jpermission\ 2£ksubjectuuida*iresources\82¤dhrefm/oic/sec/doxmcrel`brt`bif`¤dhrefn/oic/sec/pstatcrel`brt`bif`jpermission\ 6£ksubjectuuidx$31313131-3131-3131-3131-313131313131iresources\82¤dhrefj/oic/lightcrel`brt`bif`¤dhrefh/oic/fancrel`brt`bif`jpermission\18\1f£ksubjectuuidx$33333333-3333-3333-3333-333333333333iresources\82¤dhrefj/oic/lightcrel`brt`bif`¤dhrefk/oic/garagecrel`brt`bif`jpermission\18\1fjrowneruuidx$32323232-3232-3232-3232-323232323232ÿ
\ No newline at end of file
{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl"
- ],
- "perms": 2,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 6,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- },
- {
- "sub": "MTExMTExMTExMTExMTExMQ==",
- "rsrc": [
- "/oic/light",
- "/oic/fan"
- ],
- "perms": 255,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- },
- {
- "sub": "MzMzMzMzMzMzMzMzMzMzMw==",
- "rsrc": [
- "/oic/light",
- "/oic/garage"
- ],
- "perms": 255,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg==",
- "NDQ0NDQ0NDQ0NDQ0NDQ0NA=="
- ]
- }
- ]
+ "acl": {
+ "aclist": {
+ "aces": [
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/res",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/p",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/res/types/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/ad",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/acl",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 2
+ },
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/sec/doxm",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/pstat",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 6
+ },
+ {
+ "subjectuuid": "31313131-3131-3131-3131-313131313131",
+ "resources": [
+ {
+ "href": "/oic/light",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/fan",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 31
+ },
+ {
+ "subjectuuid": "33333333-3333-3333-3333-333333333333",
+ "resources": [
+ {
+ "href": "/oic/light",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/garage",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 31
+ }
+ ]
+ },
+ "rowneruuid" : "32323232-3232-3232-3232-323232323232"
+ }
}
+
--- /dev/null
+¿caclY\ 1X¢faclist¡daces\81£ksubjectuuida*iresources\88¤dhrefh/oic/rescrel`brt`bif`¤dhreff/oic/dcrel`brt`bif`¤dhreff/oic/pcrel`brt`bif`¤dhrefp/oic/res/types/dcrel`brt`bif`¤dhrefg/oic/adcrel`brt`bif`¤dhrefl/oic/sec/aclcrel`brt`bif`¤dhrefm/oic/sec/doxmcrel`brt`bif`¤dhrefn/oic/sec/pstatcrel`brt`bif`jpermission\ 2jrowneruuidx$32323232-3232-3232-3232-323232323232ÿ
\ No newline at end of file
{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl",
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : [
- "MjIyMjIyMjIyMjIyMjIyMg=="
- ]
- }
- ]
+ "acl": {
+ "aclist": {
+ "aces": [
+ {
+ "subjectuuid": "*",
+ "resources": [
+ {
+ "href": "/oic/res",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/p",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/res/types/d",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/ad",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/acl",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/doxm",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ },
+ {
+ "href": "/oic/sec/pstat",
+ "rel": "",
+ "rt": "",
+ "if": ""
+ }
+ ],
+ "permission": 2
+ }
+ ]
+ },
+ "rowneruuid" : "32323232-3232-3232-3232-323232323232"
+ }
}
#include "ocstack.h"
#include "cainterface.h"
#include "srmresourcestrings.h"
+#include "securevirtualresourcetypes.h"
using namespace std;
char g_resource1[] = "Resource1";
char g_resource2[] = "Resource2";
+extern OicSecDoxm_t *gDoxm;
+
//Policy Engine Core Tests
TEST(PolicyEngineCore, InitPolicyEngine)
{
EXPECT_EQ(OC_STACK_OK, InitPolicyEngine(&g_peContext));
}
+// TODO - in order to unittest this we need InitDoxmResource() to put doxm
+// into Owned state with a known owner. This will have to be done post v1.1.
TEST(PolicyEngineCore, CheckPermissionNoAcls)
{
- EXPECT_EQ(ACCESS_DENIED_SUBJECT_NOT_FOUND,
- CheckPermission(&g_peContext,
- &g_subjectIdA,
- g_resource1,
- PERMISSION_READ));
+ if(OC_STACK_OK == InitDoxmResource())
+ {
+ EXPECT_EQ(ACCESS_DENIED_SUBJECT_NOT_FOUND,
+ CheckPermission(&g_peContext,
+ &g_subjectIdA,
+ g_resource1,
+ PERMISSION_READ));
+ }
+ else
+ {
+ printf("%s WARNING: InitDoxmResource() returned ERROR!\n", \
+ PE_UT_TAG);
+ }
}
-//TODO This won't work until we figure out how to OcInit() or equivalent.
+// TODO - in order to unittest this we need InitDoxmResource() to put doxm
+// into Owned state with a known owner. This will have to be done post v1.1.
TEST(PolicyEngineCore, CheckDevOwnerRequest)
{
if(OC_STACK_OK == InitDoxmResource())
}
else
{
- printf("%s WARNING: InitDoxmResource() returned ERROR!\n", \
+ printf("%s WARNING: GetDoxmDevOwnerId() returned ERROR!\n", \
PE_UT_TAG);
}
}
else
{
- printf("%s WARNING: GetDoxmDevOwnerId() returned ERROR!\n", PE_UT_TAG);
+ printf("%s WARNING: InitDoxmResource() returned ERROR!\n", \
+ PE_UT_TAG);
}
-
-
}
TEST(PolicyEngineCore, DeInitPolicyEngine)
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <unistd.h>
#include "gtest/gtest.h"
+
+#include "ocpayload.h"
#include "ocstack.h"
-#include "resourcemanager.h"
-#include "pstatresource.h"
#include "oic_malloc.h"
-#include "cJSON.h"
-#include "base64.h"
#include "cainterface.h"
+#include "resourcemanager.h"
#include "secureresourcemanager.h"
-#include "srmtestcommon.h"
-#include "ocpayload.h"
-#include <unistd.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-//Declare Provision status resource methods for testing
-OCStackResult CreatePstatResource();
-OCEntityHandlerResult PstatEntityHandler (OCEntityHandlerFlag flag,
- OCEntityHandlerRequest * ehRequest);
-char * BinToPstatJSON(const OicSecPstat_t * pstat);
-OicSecPstat_t * JSONToPstatBin(const char * jsonStr);
-const char* UNIT_TEST_JSON_FILE_NAME = "oic_unittest.json";
-#ifdef __cplusplus
-}
-#endif
+#include "pstatresource.h"
+#include "security_internals.h"
-//InitPstatResource Tests
-TEST(InitPstatResourceTest, InitPstatResource)
+// InitPstatResource Tests
+TEST(PstatResourceTest, InitPstatResource)
{
- EXPECT_EQ(OC_STACK_INVALID_PARAM, InitPstatResource());
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, InitPstatResource());
}
-
-//DeInitPstatResource Tests
-TEST(DeInitPstatResourceTest, DeInitPstatResource)
+// DeInitPstatResource Tests
+TEST(PstatResourceTest, DeInitPstatResource)
{
EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitPstatResource());
}
//CreatePstatResource Tests
-TEST(CreatePstatResourceTest, CreatePstatResource)
+TEST(PstatResourceTest, CreatePstatResource)
{
- EXPECT_EQ(OC_STACK_INVALID_PARAM, CreatePstatResource());
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CreatePstatResource());
}
//PstatEntityHandler Tests
-TEST(PstatEntityHandlerTest, PstatEntityHandlerWithDummyRequest)
+TEST(PstatResourceTest, PstatEntityHandlerWithDummyRequest)
{
- OCEntityHandlerRequest req;
+ OCEntityHandlerRequest req = OCEntityHandlerRequest();
EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
}
-TEST(PstatEntityHandlerTest, PstatEntityHandlerWithPostRequest)
+TEST(PstatResourceTest, PstatEntityHandlerWithPostRequest)
{
- OCEntityHandlerRequest req;
+ OicSecPstat_t *defaultPstat = (OicSecPstat_t *) OICCalloc(1, sizeof(*defaultPstat));
+ ASSERT_TRUE(defaultPstat != NULL);
+ defaultPstat->isOp = false;
+ uint8_t deviceId[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x69, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x5a, 0x9f};
+ memcpy(defaultPstat->deviceID.id, deviceId, sizeof(deviceId));
+ EXPECT_EQ(sizeof(defaultPstat->deviceID.id), sizeof(deviceId));
+ defaultPstat->commitHash = 1234;
+ defaultPstat->cm = (OicSecDpm_t) 63;
+ defaultPstat->tm = (OicSecDpm_t) 48;
+ defaultPstat->om = (OicSecDpom_t) 0;
+ defaultPstat->smLen = 1;
+ defaultPstat->sm = (OicSecDpom_t *)OICCalloc(defaultPstat->smLen, sizeof(*defaultPstat->sm));
+ ASSERT_TRUE(defaultPstat->sm != NULL);
+ defaultPstat->sm[0] = (OicSecDpom_t) 3;
+ size_t size = 0;
+ uint8_t *cbor = NULL;
+ EXPECT_EQ(OC_STACK_OK, PstatToCBORPayload(defaultPstat, &cbor, &size));
+ DeletePstatBinData(defaultPstat);
+ ASSERT_TRUE(cbor != NULL);
+
+ OCEntityHandlerRequest req = OCEntityHandlerRequest();
req.method = OC_REST_POST;
- req.payload = reinterpret_cast<OCPayload*>(
- OCSecurityPayloadCreate("{ \"pstat\": { \"tm\": 0, \"om\": 3 }}"));
+ req.payload = (OCPayload *) OCSecurityPayloadCreate(cbor, size);
EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
+ OICFree(cbor);
OCPayloadDestroy(req.payload);
}
-TEST(PstatEntityHandlerTest, PstatEntityHandlerInvalidRequest)
+TEST(PstatResourceTest, PstatEntityHandlerInvalidRequest)
{
EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, NULL));
}
-//BinToJSON Tests
-TEST(BinToJSONTest, BinToNullJSON)
+TEST(PstatResourceTest, PstatToCBORPayloadNULL)
{
- char* value = BinToPstatJSON(NULL);
- EXPECT_TRUE(value == NULL);
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(NULL, NULL, 0));
+ // Case when cbor payload is NULL
+ OicSecPstat_t pstat;
+ size_t size = 10;
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(&pstat, NULL, &size));
+ uint8_t *cborPayload = (uint8_t *) OICCalloc(1, size);
+ ASSERT_TRUE(NULL != cborPayload);
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(&pstat, &cborPayload, &size));
+ OICFree(cborPayload);
+ cborPayload = NULL;
+ // Case when pstat is zero.
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(NULL, &cborPayload, &size));
+ // Case when size is 0.
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(&pstat, &cborPayload, 0));
+ OICFree(cborPayload);
}
-TEST(JSONToBinTest, NullJSONToBin)
+TEST(PstatResourceTest, CBORPayloadToPstat)
{
- OicSecPstat_t *pstat1 = JSONToPstatBin(NULL);
- EXPECT_TRUE(pstat1 == NULL);
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToPstat(NULL, 0, NULL));
}
-TEST(MarshalingAndUnMarshalingTest, BinToPstatJSONAndJSONToPstatBin)
+TEST(PstatResourceTest, PstatToCBORPayloadAndCBORPayloadToPstat)
{
- const char* id = "ZGV2aWNlaWQAAAAAABhanw==";
OicSecPstat_t pstat;
pstat.cm = NORMAL;
pstat.commitHash = 0;
- uint32_t outLen = 0;
- unsigned char base64Buff[sizeof(((OicUuid_t*) 0)->id)] = {};
- EXPECT_EQ(B64_OK, b64Decode(id, strlen(id), base64Buff, sizeof(base64Buff), &outLen));
- memcpy(pstat.deviceID.id, base64Buff, outLen);
+ uint8_t deviceId[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x69, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x5a, 0x9f};
+ memcpy(pstat.deviceID.id, deviceId, sizeof(deviceId));
pstat.isOp = true;
pstat.tm = NORMAL;
pstat.om = SINGLE_SERVICE_CLIENT_DRIVEN;
- pstat.smLen = 2;
- pstat.sm = (OicSecDpom_t*)OICCalloc(pstat.smLen, sizeof(OicSecDpom_t));
- if(!pstat.sm)
- {
- FAIL() << "Failed to allocate the pstat.sm";
- }
+ pstat.smLen = 1;
+ pstat.sm = (OicSecDpom_t*)OICCalloc(pstat.smLen, sizeof(*pstat.sm));
+ ASSERT_TRUE(NULL != pstat.sm);
pstat.sm[0] = SINGLE_SERVICE_CLIENT_DRIVEN;
- pstat.sm[1] = SINGLE_SERVICE_SERVER_DRIVEN;
- char* jsonPstat = BinToPstatJSON(&pstat);
- if(!jsonPstat)
+
+ size_t size = 0;
+ uint8_t *cbor = NULL;
+ EXPECT_EQ(OC_STACK_OK, PstatToCBORPayload(&pstat, &cbor, &size));
+ if (!cbor)
{
OICFree(pstat.sm);
- FAIL() << "Failed to convert BinToPstatJSON";
+ FAIL() << "Failed to convert PstatToCBORPayload";
return;
}
- printf("BinToJSON Dump:\n%s\n\n", jsonPstat);
- EXPECT_TRUE(jsonPstat != NULL);
- OicSecPstat_t *pstat1 = JSONToPstatBin(jsonPstat);
- EXPECT_TRUE(pstat1 != NULL);
- if(pstat1)
- {
- OICFree(pstat1->sm);
- }
- OICFree(pstat1);
- OICFree(jsonPstat);
- OICFree(pstat.sm);
-}
-
-TEST(PstatTests, JSONMarshalliingTests)
-{
- char *jsonStr1 = ReadFile(UNIT_TEST_JSON_FILE_NAME);
- if (NULL != jsonStr1)
- {
- cJSON_Minify(jsonStr1);
- /* Workaround : cJSON_Minify does not remove all the unwanted characters
- from the end. Here is an attempt to remove those characters */
- int len = strlen(jsonStr1);
- while (len > 0)
- {
- if (jsonStr1[--len] == '}')
- {
- break;
- }
- }
- jsonStr1[len + 1] = 0;
-
- OicSecPstat_t* pstat = JSONToPstatBin(jsonStr1);
- EXPECT_TRUE(NULL != pstat);
-
- char* jsonStr2 = BinToPstatJSON(pstat);
- EXPECT_STRNE(jsonStr1, jsonStr2);
+ ASSERT_TRUE(NULL != cbor);
+ OicSecPstat_t *pstat1 = NULL;
+ EXPECT_EQ(OC_STACK_OK, CBORPayloadToPstat(cbor, size, &pstat1));
+ ASSERT_TRUE(NULL != pstat1);
+ EXPECT_EQ(pstat.commitHash, pstat1->commitHash);
+ EXPECT_EQ(pstat.isOp, pstat1->isOp);
+ EXPECT_EQ(pstat.tm, pstat1->tm);
+ EXPECT_EQ(pstat.om, pstat1->om);
+ EXPECT_EQ(pstat.smLen, pstat1->smLen);
+ EXPECT_EQ(pstat.sm[0], pstat1->sm[0]);
- OICFree(jsonStr1);
- OICFree(jsonStr2);
- OICFree(pstat);
- }
- else
- {
- printf("Please copy %s into unittest folder\n", UNIT_TEST_JSON_FILE_NAME);
- }
+ DeletePstatBinData(pstat1);
+ OICFree(cbor);
+ OICFree(pstat.sm);
}
#include "gtest/gtest.h"
#include "oic_malloc.h"
#include "ocstack.h"
+#include <stdlib.h>
+#include "cbor.h"
+#define STRINGIZE2(x) #x
+#define STRINGIZE(x) STRINGIZE2(x)
+
+// TODO: Remove this, once all cbor related are completed.
char* ReadFile(const char* filename)
{
return data;
}
+bool ReadCBORFile(const char* filename, const char* rsrcname, uint8_t **payload, size_t *pSize)
+{
+ bool status = false;
+ if (!payload || !pSize)
+ {
+ printf("Passed parameter are INVALID \n");
+ return status;
+ }
+ uint8_t *data = NULL;
+ size_t size = 0;
+
+ int len = strlen(STRINGIZE(SECURITY_BUILD_UNITTEST_DIR)) + strlen(filename) + 1;
+ char *filepath = (char *)OICCalloc(1, len);
+ if (!filepath)
+ {
+ printf("filepath memory allocation failed. \n");
+ return false;
+ }
+ int ret = snprintf(filepath, len, "%s%s", STRINGIZE(SECURITY_BUILD_UNITTEST_DIR), filename);
+ printf("Root build path: %s \n", filepath);
+
+ if (ret == len-1)
+ {
+ FILE *fp = fopen(filepath, "rb");
+ if (fp)
+ {
+ struct stat st;
+ if (stat(filepath, &st) == 0)
+ {
+ data = (uint8_t *)OICMalloc(st.st_size);
+ if (data)
+ {
+ if (fread(data, 1, st.st_size, fp) != (size_t)st.st_size)
+ {
+ printf("Error in reading file %s\n", filename);
+ }
+ else
+ {
+ size = st.st_size;
+
+ CborValue cbor = {0, };
+ CborParser parser = {0, };
+ cbor_parser_init(data, size, 0, &parser, &cbor);
+ CborError cborFindResult = CborNoError;
+
+ CborValue curVal = {0, };
+ cborFindResult = cbor_value_map_find_value(&cbor, rsrcname, &curVal);
+ if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+ {
+ cborFindResult = cbor_value_dup_byte_string(&curVal, payload, pSize, NULL);
+ if(CborNoError != cborFindResult)
+ {
+ printf("Failed to getting %s data\n", rsrcname);
+ }
+ else
+ {
+ status = true;
+ }
+ }
+ else
+ {
+ printf("Failed to finding %s data\n", rsrcname);
+ }
+
+ }
+ OICFree(data);
+ }
+ }
+ fclose(fp);
+ }
+ else
+ {
+ printf("Unable to open %s file\n", filepath);
+ }
+ }
+ else
+ {
+ printf("Filepath copy failed.\n");
+ }
+ OICFree(filepath);
+ return status;
+}
+
void SetPersistentHandler(OCPersistentStorage *ps, bool set)
{
if (set)
#define IOTVT_SRM_TEST_COMMON_H
char* ReadFile(const char* filename);
+bool ReadCBORFile(const char* filename, const char* rsrcName, uint8_t **payload, size_t *size);
void SetPersistentHandler(OCPersistentStorage *ps, bool set);
#endif //IOTVT_SRM_TEST_COMMON_H
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#include "gtest/gtest.h"
-#include <pwd.h>
-#include <grp.h>
-#include <linux/limits.h>
-#include <sys/stat.h>
#include "ocstack.h"
#include "oic_malloc.h"
-#include "cJSON.h"
#include "cainterface.h"
#include "secureresourcemanager.h"
#include "securevirtualresourcetypes.h"
#include "srmresourcestrings.h"
#include "svcresource.h"
#include "srmtestcommon.h"
+#include "security_internals.h"
using namespace std;
-#ifdef __cplusplus
-extern "C" {
-#endif
-extern char * BinToSvcJSON(const OicSecSvc_t * svc);
-extern OicSecSvc_t * JSONToSvcBin(const char * jsonStr);
-extern void DeleteSVCList(OicSecSvc_t* svc);
-#ifdef __cplusplus
-}
-#endif
-
-static const char* JSON_FILE_NAME = "oic_unittest.json";
-
-#define NUM_SVC_IN_JSON_DB (2)
+#define NUM_SVC_IN_CBOR_DB (2)
-
-// JSON Marshalling Tests
-TEST(SVCResourceTest, JSONMarshallingTests)
+TEST(SVCResourceTest, CBORConversionTests)
{
- char *jsonStr1 = ReadFile(JSON_FILE_NAME);
- if (jsonStr1)
- {
- OicSecSvc_t * svc = JSONToSvcBin(jsonStr1);
- EXPECT_TRUE(NULL != svc);
+ OicSecSvc_t *svc1 = (OicSecSvc_t *) OICCalloc(1, sizeof(*svc1));
+ ASSERT_TRUE(NULL != svc1);
+ uint8_t svcdid[] = {0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
+ 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35};
+ memcpy(svc1->svcdid.id, svcdid, sizeof(svcdid));
+ ASSERT_EQ(sizeof(svc1->svcdid.id), sizeof(svcdid));
- int cnt = 0;
- OicSecSvc_t * tempSvc = svc;
- while(tempSvc)
- {
+ svc1->svct = (OicSecSvcType_t) 1;
+ uint8_t owners[] = {0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
+ 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39};
+ svc1->ownersLen = 1;
+ svc1->owners = (OicUuid_t *)OICCalloc(svc1->ownersLen, sizeof(*svc1->owners));
+ ASSERT_TRUE(NULL != svc1->owners);
+ memcpy(svc1->owners[0].id, owners, sizeof(owners));
+ ASSERT_EQ(sizeof(svc1->owners[0].id), sizeof(owners));
- EXPECT_EQ(tempSvc->svct, ACCESS_MGMT_SERVICE);
- cnt++;
- tempSvc = tempSvc->next;
- }
- EXPECT_EQ(cnt, NUM_SVC_IN_JSON_DB);
+ svc1->next = (OicSecSvc_t *) OICCalloc(1, sizeof(*svc1->next));
+ ASSERT_TRUE(svc1->next != NULL);
+ memcpy(svc1->next->svcdid.id, svcdid, sizeof(svcdid));
+ ASSERT_EQ(sizeof(svc1->next->svcdid.id), sizeof(svcdid));
+ svc1->next->svct = (OicSecSvcType_t) 1;
+ uint8_t owners1[] = {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36};
+ svc1->next->ownersLen = 1;
+ svc1->next->owners = (OicUuid_t *)OICCalloc(svc1->next->ownersLen,
+ sizeof(*svc1->next->owners));
+ ASSERT_TRUE(NULL != svc1->next->owners);
+ memcpy(svc1->next->owners[0].id, owners1, sizeof(owners1));
+ svc1->next->next = NULL;
- char * jsonStr2 = BinToSvcJSON(svc);
- EXPECT_TRUE(NULL != jsonStr2);
+ size_t size = 0;
+ uint8_t *psStorage = NULL;
+ EXPECT_EQ(OC_STACK_OK, SVCToCBORPayload(svc1, &psStorage, &size));
+ ASSERT_TRUE(NULL != psStorage);
- OICFree(jsonStr1);
- OICFree(jsonStr2);
- DeleteSVCList(svc);
+ OicSecSvc_t *svc = NULL;
+ EXPECT_EQ(OC_STACK_OK, CBORPayloadToSVC(psStorage, size, &svc));
+ ASSERT_TRUE(NULL != svc);
+
+ int cnt = 0;
+ OicSecSvc_t *tempSvc = svc;
+ while (tempSvc)
+ {
+ EXPECT_EQ(ACCESS_MGMT_SERVICE, tempSvc->svct);
+ cnt++;
+ tempSvc = tempSvc->next;
}
-}
+ EXPECT_EQ(NUM_SVC_IN_CBOR_DB, cnt);
+ OICFree(psStorage);
+ DeleteSVCList(svc);
+ DeleteSVCList(svc1);
+}
// Discovery Payload
OCDiscoveryPayload* OCDiscoveryPayloadCreate();
-OCSecurityPayload* OCSecurityPayloadCreate(const char* securityData);
+OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size);
void OCSecurityPayloadDestroy(OCSecurityPayload* payload);
void OCDiscoveryPayloadAddResource(OCDiscoveryPayload* payload, const OCResource* res,
/**
* Error code from OTM
- * This error is plused from DTLS interface when handshake failure happens
+ * This error is pushed from DTLS interface when handshake failure happens
*/
OC_STACK_AUTHENTICATION_FAILURE,
* Persistent storage handlers. An APP must provide OCPersistentStorage handler pointers
* when it calls OCRegisterPersistentStorageHandler.
* Persistent storage open handler points to default file path.
+ * It should check file path and whether the file is symbolic link or no.
* Application can point to appropriate SVR database path for it's IoTivity Server.
*/
typedef struct {
/** Enum to describe the type of object held by the OCPayload object.*/
typedef enum
{
+ /** Contents of the payload are invalid */
PAYLOAD_TYPE_INVALID,
+ /** The payload is an OCDiscoveryPayload */
PAYLOAD_TYPE_DISCOVERY,
+ /** The payload is an OCDevicePayload */
PAYLOAD_TYPE_DEVICE,
+ /** The payload is an OCPlatformPayload */
PAYLOAD_TYPE_PLATFORM,
+ /** The payload is an OCRepPayload */
PAYLOAD_TYPE_REPRESENTATION,
+ /** The payload is an OCSecurityPayload */
PAYLOAD_TYPE_SECURITY,
+ /** The payload is an OCPresencePayload */
PAYLOAD_TYPE_PRESENCE,
+ /** The payload is an OCRDPayload */
PAYLOAD_TYPE_RD
} OCPayloadType;
+/**
+ * A generic struct representing a payload returned from a resource operation
+ *
+ * A pointer to OCPayLoad can be cast to a more specific struct to access members
+ * for the its type.
+ */
typedef struct
{
- // The type of message that was received
+ /** The type of message that was received */
OCPayloadType type;
} OCPayload;
typedef struct
{
OCPayload base;
- char* securityData;
+ uint8_t* securityData;
+ size_t payloadSize;
} OCSecurityPayload;
+
#ifdef WITH_PRESENCE
typedef struct
{
} OCEntityHandlerFlag;
/**
- * Possible returned values from client application.
+ * Possible return values from client application callback
+ *
+ * A client application callback returns an OCStackApplicationResult to indicate whether
+ * the stack should continue to keep the callback registered.
*/
typedef enum
{
+ /** Make no more calls to the callback and call the OCClientContextDeleter for this callback */
OC_STACK_DELETE_TRANSACTION = 0,
+ /** Keep this callback registered and call it if an apropriate event occurs */
OC_STACK_KEEP_TRANSACTION
} OCStackApplicationResult;
if env.get('SECURED') == '1':
samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
sec_samples_src_dir + 'oic_svr_db_client_directpairing.json'))
+ samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
+ sec_samples_src_dir + 'oic_svr_db_client_directpairing.dat'))
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
+ sec_samples_src_dir + 'oic_svr_db_server.dat'))
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
+ sec_samples_src_dir + 'oic_svr_db_client.dat'))
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
+ sec_samples_src_dir + 'oic_amss_db.dat'))
//AMS service database, hold AMS service Identity and
//the PSK credentials of trusted devices
-static char AMSS_DB_FILE[] = "oic_amss_db.json";
+static char AMSS_DB_FILE[] = "oic_amss_db.dat";
/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
void handleSigInt(int signum)
//Secure Virtual Resource database for Iotivity Client application
//It contains Client's Identity and the PSK credentials
//of other devices which the client trusts
-static char CRED_FILE[] = "oic_svr_db_client.json";
+static char CRED_FILE[] = "oic_svr_db_client.dat";
int gQuitFlag = 0;
//Secure Virtual Resource database for Iotivity Client application\r
//It contains Client's Identity and the PSK credentials\r
//of other devices which the client trusts\r
-static char CRED_FILE[] = "oic_svr_db_client_directpairing.json";\r
-\r
+static char CRED_FILE[] = "oic_svr_db_client_directpairing.dat";
+
static const OCDPDev_t *discoveredDevs = NULL;\r
static const OCDPDev_t *pairedDevs = NULL;\r
\r
OIC_LOG(ERROR, TAG, "Invalid PIN");\r
continue;\r
}\r
- sscanf(input, "%9s", pinNumber);\r
- printf("\n");\r
+ sscanf(input, "%8s", pinNumber);
+ printf("\n");
\r
ret = DoDirectPairing(peer, pmSel, pinNumber);\r
if (OC_STACK_OK != ret)\r
\r
return 0;\r
}\r
-\r
-\r
-\r
//Secure Virtual Resource database for Iotivity Server
//It contains Server's Identity and the PSK credentials
//of other devices which the server trusts
-static char CRED_FILE[] = "oic_svr_db_server.json";
+static char CRED_FILE[] = "oic_svr_db_server.dat";
OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
{
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl",
- "/oic/sec/amacl"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
- "rsrc": ["/oic/sec/acl",
- "/oic/sec/cred"],
- "perms": 8,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "sub": "NDQ0NDMzMzMyMjIyMTExMQ==",
- "rsrc": ["/a/led"],
- "perms": 6,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MTkxOTE5MTkxOTE5MTkxOQ==",
- "ownr": "YWRtaW5EZXZpY2VVVUlEAA=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MTExMTExMTExMTExMTExMQ==",
- "credtyp": 1,
- "pvdata": "QkJCQkJCQkJCQkJCQkJCQg==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/amacl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "31393139-3139-3139-3139-313931393139"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "31393139-3139-3139-3139-313931393139",\r
+ "rowneruuid": "31393139-3139-3139-3139-313931393139",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "31393139-3139-3139-3139-313931393139",\r
+ "devowneruuid": "61646D69-6E44-6576-6963-655555494430",\r
+ "rowneruuid": "31393139-3139-3139-3139-313931393139",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "31313131-3131-3131-3131-313131313131",\r
+ "credtype": 1,\r
+ "privatedata": {\r
+ "data": "BBBBBBBBBBBBBBBB",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232"\r
+ }\r
+}
\ No newline at end of file
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl",
- "/oic/sec/amacl"
- ],
- "perms": 2,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MjIyMjIyMjIyMjIyMjIyMg==",
- "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MTExMTExMTExMTExMTExMQ==",
- "credtyp": 1,
- "prd": "20150630T060000/20990920T220000",
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/amacl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "32323232-3232-3232-3232-323232323232"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+ "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "31313131-3131-3131-3131-313131313131",\r
+ "credtype": 1,\r
+ "privatedata": {\r
+ "data": "AAAAAAAAAAAAAAAA",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232"\r
+ }\r
+}\r
{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/res/d",
- "/oic/res/types/d",
- "/oic/presence"
- ],
- "perms": 2,
- "ownrs" : [
- "ZGlyZWN0cGFpcmluZ0Rldg=="
- ]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat",
- "/oic/sec/acl",
- "/oic/sec/cred"
- ],
- "perms": 6,
- "ownrs" : [
- "ZGlyZWN0cGFpcmluZ0Rldg=="
- ]
- }
- ],
- "pstat": {
- "isop": false,
- "deviceid": "ZGlyZWN0cGFpcmluZ0Rldg==",
- "commithash": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": false,
- "deviceid": "ZGlyZWN0cGFpcmluZ0Rldg=="
- }
-}
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/presence",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/cred",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "64697265-6374-7061-6972-696e67446576"\r
+ },\r
+ "pstat": {\r
+ "isop": false,\r
+ "deviceuuid": "64697265-6374-7061-6972-696e67446576",\r
+ "rowneruuid": "64697265-6374-7061-6972-696e67446576",\r
+ "cm": 2,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": false,\r
+ "deviceuuid": "64697265-6374-7061-6972-696e67446576",\r
+ "devowneruuid": "",\r
+ "rowneruuid": "64697265-6374-7061-6972-696e67446576",\r
+ "dpc": false\r
+ }\r
+}\r
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl",
- "/oic/sec/amacl"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
- "rsrc": ["/oic/sec/acl",
- "/oic/sec/cred"],
- "perms": 8,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
- "rsrc": ["/a/led"],
- "perms": 6,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "sub": "MTExMTIyMjIzMzMzNDQ0NA==",
- "rsrc": ["/a/led"],
- "perms": 6,
- "prds" : ["20150630T060000/20150630T220000", "20150630T060000/20150630T200000"],
- "recurs" : ["FREQ=DAILY; BYDAY=MO, WE, FR", "FREQ=DAILY; BYDAY=TU, TH; UNTIL=20160630"],
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "sub": "Nzc3Nzc3Nzc3Nzc3Nzc3Nw==",
- "rsrc": ["/a/led"],
- "perms": 6,
- "prds" : ["20150630T060000/20150630T220000"],
- "recurs" : ["FREQ=DAILY; UNTIL=20150630"],
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "amacl": [{
- "rsrc" : ["/a/led"],
- "amss" : ["MTkxOTE5MTkxOTE5MTkxOQ=="],
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MTExMTExMTExMTExMTExMQ==",
- "ownr": "YWRtaW5EZXZpY2VVVUlEAA=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "credid": 2,
- "sub": "MTExMTIyMjIzMzMzNDQ0NA==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "credid": 3,
- "sub": "Nzc3Nzc3Nzc3Nzc3Nzc3Nw==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "credid": 4,
- "sub": "NDQ0NDMzMzMyMjIyMTExMQ==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "credid": 5,
- "sub": "MTkxOTE5MTkxOTE5MTkxOQ==",
- "credtyp": 1,
- "pvdata": "QkJCQkJCQkJCQkJCQkJCQg==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/amacl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "32323232-3232-3232-3232-323232323232",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/cred",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 8\r
+ },\r
+ {\r
+ "subjectuuid": "31313131-3232-3232-3333-333334343434",\r
+ "resources": [\r
+ {\r
+ "href": "/a/led",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6,\r
+ "period" : ["20150630T060000/20150630T220000", "20150630T060000/20150630T200000"],\r
+ "recurrence" : ["FREQ=DAILY; BYDAY=MO, WE, FR", "FREQ=DAILY; BYDAY=TU, TH; UNTIL=20160630"]\r
+ },\r
+ {\r
+ "subjectuuid": "37373737-3737-3737-3737-373737373737",\r
+ "resources": [\r
+ {\r
+ "href": "/a/led",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6,\r
+ "period" : ["20150630T060000/20150630T220000"],\r
+ "recurrence" : ["FREQ=DAILY; UNTIL=20150630"]\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "31313131-3131-3131-3131-313131313131"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+ "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "32323232-3232-3232-3232-323232323232",\r
+ "credtype": 1,\r
+ "period": "20150630T060000/20990920T220000",\r
+ "privatedata": {\r
+ "data": "AAAAAAAAAAAAAAAA",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ },\r
+ {\r
+ "credid": 2,\r
+ "subjectuuid": "31393139-3139-3139-3139-313931393139",\r
+ "credtype": 1,\r
+ "period": "20150630T060000/20990920T220000",\r
+ "privatedata": {\r
+ "data": "BBBBBBBBBBBBBBBB",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232"\r
+ }\r
+}\r
{
case OCREP_PROP_INT:
dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.iArray, "Failed allocating memory");
memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
break;
case OCREP_PROP_DOUBLE:
dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.dArray, "Failed allocating memory");
memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
break;
case OCREP_PROP_BOOL:
dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.bArray, "Failed allocating memory");
memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
break;
case OCREP_PROP_STRING:
dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.strArray, "Failed allocating memory");
for(size_t i = 0; i < dimTotal; ++i)
{
dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
break;
case OCREP_PROP_OBJECT:
dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
for(size_t i = 0; i < dimTotal; ++i)
{
dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
break;
case OCREP_PROP_ARRAY:
dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+ VERIFY_PARAM_NON_NULL(TAG, dest->arr.objArray, "Failed allocating memory");
for(size_t i = 0; i < dimTotal; ++i)
{
dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
OIC_LOG(ERROR, TAG, "CopyPropertyValueArray invalid type");
break;
}
+exit:
+ return;
}
static void OCCopyPropertyValue (OCRepPayloadValue *dest, OCRepPayloadValue *source)
{
OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
- if (!val || val->type != OCREP_PROP_DOUBLE)
+ if (val)
{
- return false;
+ if (val->type == OCREP_PROP_DOUBLE)
+ {
+ *value = val->d;
+ return true;
+ }
+ else if (val->type == OCREP_PROP_INT)
+ {
+ *value = val->i;
+ return true;
+ }
}
- *value = val->d;
- return true;
+ return false;
}
bool OCRepPayloadSetPropString(OCRepPayload* payload, const char* name, const char* value)
{
OCRepPayloadValue* val = OCRepPayloadFindValue(payload, name);
- if (!val || val->type != OCREP_PROP_ARRAY || val->arr.type != OCREP_PROP_DOUBLE
+ if (!val || val->type != OCREP_PROP_ARRAY ||
+ (val->arr.type != OCREP_PROP_DOUBLE && val->arr.type != OCREP_PROP_INT)
|| !val->arr.dArray)
{
return false;
return false;
}
- memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
+ if (val->arr.type != OCREP_PROP_DOUBLE)
+ {
+ memcpy(*array, val->arr.dArray, dimTotal * sizeof(double));
+ }
+ else
+ {
+ /* need to convert from integer */
+ size_t n = 0;
+ for ( ; n < dimTotal; ++n)
+ {
+ (*array)[n] = val->arr.iArray[n];
+ }
+ }
memcpy(dimensions, val->arr.dimensions, MAX_REP_ARRAY_DEPTH * sizeof(size_t));
return true;
}
return payload;
}
-OCSecurityPayload* OCSecurityPayloadCreate(const char* securityData)
+OCSecurityPayload* OCSecurityPayloadCreate(const uint8_t* securityData, size_t size)
{
OCSecurityPayload* payload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
}
payload->base.type = PAYLOAD_TYPE_SECURITY;
- payload->securityData = OICStrdup(securityData);
+ payload->securityData = (uint8_t *)OICCalloc(1, size);
+ if (!payload->securityData)
+ {
+ OICFree(payload);
+ return NULL;
+ }
+ memcpy(payload->securityData, (uint8_t *)securityData, size);
+ payload->payloadSize = size;
return payload;
}
if (!*stringLL)
{
*stringLL = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
- VERIFY_PARAM_NON_NULL(TAG, dup, "Failed allocating memory");
+ VERIFY_PARAM_NON_NULL(TAG, *stringLL, "Failed allocating memory");
(*stringLL)->value = dup;
return true;
}
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);
+ memcpy(outPayload, payload->securityData, payload->payloadSize);
+ *size = payload->payloadSize;
- 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");
- }
-
- 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 int64_t OCStringLLJoin(CborEncoder *map, char *type, OCStringLL *val)
static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot);
static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
-static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, CborValue * rrayVal);
+static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, const uint8_t *payload, size_t size);
OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
const uint8_t *payload, size_t payloadSize)
VERIFY_PARAM_NON_NULL(TAG, outPayload, "Conversion of outPayload failed");
VERIFY_PARAM_NON_NULL(TAG, payload, "Invalid cbor payload value");
- OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu", payloadSize);
+ OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu of Payload Type: %d, Payload:",
+ payloadSize, payloadType);
+ OIC_LOG_BUFFER(DEBUG, TAG, payload, payloadSize);
CborParser parser;
CborValue rootValue;
result = OCParsePresencePayload(outPayload, &rootValue);
break;
case PAYLOAD_TYPE_SECURITY:
- result = OCParseSecurityPayload(outPayload, &rootValue);
+ result = OCParseSecurityPayload(outPayload, payload, payloadSize);
break;
case PAYLOAD_TYPE_RD:
result = OCRDCborToPayload(&rootValue, outPayload);
void OCFreeOCStringLL(OCStringLL* ll);
-static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue)
+static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, const uint8_t *payload,
+ size_t size)
{
- OCStackResult ret = OC_STACK_MALFORMED_RESPONSE;
- CborError err;
- char *securityData = NULL;
-
- VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid parameter");
- VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid cbor");
-
- CborValue strVal;
-
- err = cbor_value_enter_container(rootValue, &strVal);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering container");
- if (cbor_value_is_text_string(&strVal))
+ if (size > 0)
{
- size_t len = 0;
- err = cbor_value_dup_text_string(&strVal, &securityData, &len, NULL);
- VERIFY_CBOR_SUCCESS(TAG, err, "Failed reading security data");
- *outPayload = (OCPayload *)OCSecurityPayloadCreate(securityData);
- VERIFY_PARAM_NON_NULL(TAG, *outPayload, "Invalid cbor");
- ret = OC_STACK_OK;
+ *outPayload = (OCPayload *)OCSecurityPayloadCreate(payload, size);
}
-
-exit:
- OICFree(securityData);
- return ret;
-
+ else
+ {
+ *outPayload = NULL;
+ }
+ return OC_STACK_OK;
}
static char* InPlaceStringTrim(char* str)
CborValue curVal;
// Resource Type
err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag");
+
if (cbor_value_is_valid(&curVal))
{
err = OCParseStringLL(rootValue, OC_RSRVD_RESOURCE_TYPE, &out->types);
// Device ID
size_t len = 0;
err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_ID, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find device id tag");
if (cbor_value_is_valid(&curVal))
{
if (cbor_value_is_byte_string(&curVal))
}
// Device Name
err = cbor_value_map_find_value(rootValue, OC_RSRVD_DEVICE_NAME, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find device name tag");
if (cbor_value_is_valid(&curVal))
{
err = cbor_value_dup_text_string(&curVal, &out->deviceName, &len, NULL);
}
// Device Spec Version
err = cbor_value_map_find_value(rootValue, OC_RSRVD_SPEC_VERSION, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find spec ver tag");
if (cbor_value_is_valid(&curVal))
{
err = cbor_value_dup_text_string(&curVal, &out->specVersion, &len, NULL);
}
// Data Model Version
err = cbor_value_map_find_value(rootValue, OC_RSRVD_DATA_MODEL_VERSION, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find data model ver tag");
if (cbor_value_is_valid(&curVal))
{
err = cbor_value_dup_text_string(&curVal, &out->dataModelVersion, &len, NULL);
// Platform ID
err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_ID, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find platform id tag");
if (cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.platformID), &len, NULL);
}
// MFG Name
err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_NAME, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg name tag");
if (cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.manufacturerName), &len, NULL);
}
// MFG URL
err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_URL, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg url tag");
if (cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.manufacturerUrl), &len, NULL);
}
// Model Num
err = cbor_value_map_find_value(rootValue, OC_RSRVD_MODEL_NUM, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find model num tag");
if (cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.modelNumber), &len, NULL);
}
// Date of Mfg
err = cbor_value_map_find_value(rootValue, OC_RSRVD_MFG_DATE, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find mfg date tag");
if (cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.dateOfManufacture), &len, NULL);
}
// Platform Version
err = cbor_value_map_find_value(rootValue, OC_RSRVD_PLATFORM_VERSION, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find platform ver tag");
if (cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.platformVersion), &len, NULL);
}
// OS Version
err = cbor_value_map_find_value(rootValue, OC_RSRVD_OS_VERSION, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find os ver tag");
if (cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.operatingSystemVersion), &len, NULL);
}
// Hardware Version
err = cbor_value_map_find_value(rootValue, OC_RSRVD_HARDWARE_VERSION, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find hw ver tag");
if(cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.hardwareVersion), &len, NULL);
}
// Firmware Version
err = cbor_value_map_find_value(rootValue, OC_RSRVD_FIRMWARE_VERSION, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find fw ver tag");
if(cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.firmwareVersion), &len, NULL);
}
// Support URL
err = cbor_value_map_find_value(rootValue, OC_RSRVD_SUPPORT_URL, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find support url tag");
if(cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.supportUrl), &len, NULL);
}
// System Time
err = cbor_value_map_find_value(rootValue, OC_RSRVD_SYSTEM_TIME, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find sys time tag");
if(cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &(info.systemTime), &len, NULL);
// Resource type
err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type tag");
+
if(cbor_value_is_valid(&repVal))
{
err = cbor_value_dup_text_string(&repVal, &rt, &len, NULL);
// Interface Types
err = cbor_value_map_find_value(rootValue, OC_RSRVD_INTERFACE, &repVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find interface tag");
+
if(cbor_value_is_valid(&repVal))
{
err = OCParseStringLL(rootValue, OC_RSRVD_INTERFACE, &interfaces);
out->rt = rt;
out->interfaces = interfaces;
*outPayload = (OCPayload *)out;
-
OIC_LOG_PAYLOAD(DEBUG, *outPayload);
-
return OC_STACK_OK;
}
case CborIntegerType:
return OCREP_PROP_INT;
case CborDoubleType:
+ case CborFloatType:
return OCREP_PROP_DOUBLE;
case CborBooleanType:
return OCREP_PROP_BOOL;
case OCREP_PROP_DOUBLE:
if (dimensions[1] == 0)
{
- err = cbor_value_get_double(&insideArray, &(((double*)targetArray)[i]));
+ double *d = &(((double*)targetArray)[i]);
+ if (cbor_value_get_type(&insideArray) == CborDoubleType)
+ {
+ err = cbor_value_get_double(&insideArray, d);
+ }
+ else
+ {
+ /* must be float */
+ float f;
+ err = cbor_value_get_float(&insideArray, &f);
+ if (!err)
+ *d = f;
+ }
}
else
{
static CborError OCParseArray(OCRepPayload *out, const char *name, CborValue *container)
{
void *arr = NULL;
+
OCRepPayloadPropType type = OCREP_PROP_NULL;
size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+
size_t dimTotal = 0;
size_t allocSize = 0;
bool res = true;
if (cbor_value_is_array(root))
{
err = cbor_value_enter_container(root, &rootMap);
+ VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering repMap");
}
while (cbor_value_is_valid(&rootMap))
{
if (cbor_value_is_map(&rootMap))
{
err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
if (cbor_value_is_valid(&curVal))
{
size_t len = 0;
// Resource type name
err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
+ VERIFY_CBOR_SUCCESS(TAG, err, "to find res type tag");
if (cbor_value_is_valid(&curVal))
{
size_t len = 0;
OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
discPayload->sid = (char *)OICCalloc(1, UUID_STRING_SIZE);
VERIFY_NON_NULL(discPayload->sid, ERROR, OC_STACK_NO_MEMORY);
- memcpy(discPayload->sid, OCGetServerInstanceIDString(), UUID_STRING_SIZE);
+
+ const char* uid = OCGetServerInstanceIDString();
+ if (uid)
+ {
+ memcpy(discPayload->sid, uid, UUID_STRING_SIZE);
+ }
+
if (!resourceTypeQuery && interfaceQuery && (0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
{
for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
requestResult = HandleStackRequests (&serverRequest);
// Send ACK to client as precursor to slow response
- if(requestResult == OC_STACK_SLOW_RESOURCE)
+ if (requestResult == OC_STACK_SLOW_RESOURCE)
{
- SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_EMPTY,
- CA_MSG_ACKNOWLEDGE,0, NULL, NULL, 0, NULL);
+ if (requestInfo->info.type == CA_MSG_CONFIRM)
+ {
+ SendDirectStackResponse(endPoint, requestInfo->info.messageId, CA_EMPTY,
+ CA_MSG_ACKNOWLEDGE,0, NULL, NULL, 0, NULL);
+ }
}
else if(requestResult != OC_STACK_OK)
{
char *resourceUri = NULL;
char *resourceType = NULL;
- // This validation is broken, but doesn't cause harm
- size_t uriLen = strlen(requestUri );
- if ((result = verifyUriQueryLength(requestUri , uriLen)) != OC_STACK_OK)
- {
- goto exit;
- }
-
/*
* Support original behavior with address on resourceUri argument.
*/
OCDirectPairingCB resultCallback)
{
OIC_LOG(INFO, TAG, "Start OCDoDirectPairing");
- if(NULL == peer)
+ if(NULL == peer || NULL == pinNumber)
{
OIC_LOG(ERROR, TAG, "Invalid parameters");
return OC_STACK_INVALID_PARAM;
}
-
- if(NULL == resultCallback)
+ if (NULL == resultCallback)
{
- OIC_LOG(ERROR, TAG, "Invalid parameters");
+ OIC_LOG(ERROR, TAG, "Invalid callback");
return OC_STACK_INVALID_CALLBACK;
}
+
gDirectpairingCallback = resultCallback;
return DPDirectPairing((OCDirectPairingDev_t*)peer, (OicSecPrm_t)pmSel,
pinNumber, DirectPairingCB);
static CborError ConditionalAddIntToMap(CborEncoder *map, const char *tags, const uint64_t *value)
{
- CborError err = CborUnknownError;
+ CborError err = CborNoError;
if (*value)
{
err = cbor_encode_text_string(map, tags, strlen(tags));
--- /dev/null
+# Doxyfile 1.8.2
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = "IoTivity C SDK"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = docs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented classes,
+# or namespaces to their corresponding documentation. Such a link can be
+# prevented in individual cases by by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES (the
+# default) will make doxygen replace the get and set methods by a property in
+# the documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields will be shown inline in the documentation
+# of the scope in which they are defined (i.e. file, namespace, or group
+# documentation), provided this scope is documented. If set to NO (the default),
+# structs, classes, and unions are shown on a separate page (for HTML and Man
+# pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be
+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given
+# their name and scope. Since this can be an expensive process and often the
+# same symbol appear multiple times in the code, doxygen keeps a cache of
+# pre-resolved symbols. If the cache is too small doxygen will become slower.
+# If the cache is too large, memory is wasted. The cache size is given by this
+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 125
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE = doxygenLayout.xml
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE = ./doxygen.log
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = . \
+ ../../csdk/security/provisioning/include/ocprovisioningmanager.h \
+ ../../csdk/security/provisioning/include/pmtypes.h \
+ ../../csdk/security/provisioning/include/pmutility.h \
+ ../../csdk/stack/include/ocstack.h \
+ ../../csdk/stack/include/octypes.h \
+ ../../csdk/stack/include/ocpayload.h \
+ ../../csdk/stack/include/ocpresence.h \
+ ../../csdk/stack/include/rdpayload.h \
+ ../../csdk/stack/include/payload_logging.h \
+ ../../csdk/stack/include/ocstackconfig.h \
+ ../../csdk/stack/include/internal/occlientcb.h \
+ ../../csdk/stack/include/internal/occollection.h \
+ ../../csdk/stack/include/internal/ocobserve.h \
+ ../../csdk/stack/include/internal/ocpayloadcbor.h \
+ ../../csdk/stack/include/internal/ocresource.h \
+ ../../csdk/stack/include/internal/ocresourcehandler.h \
+ ../../csdk/stack/include/internal/ocserverrequest.h \
+ ../../csdk/stack/include/internal/ocstackinternal.h \
+ ../../csdk/stack/include/internal/oicgroup.h \
+ ../../csdk/stack/include/internal/oickeepalive.h \
+ guides \
+ ../../../service/easy-setup/enrollee/inc \
+ ../../../service/easy-setup/enrollee/src/softap.h \
+ ../../../service/resource-directory/include \
+
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS = *.c \
+ *.cc \
+ *.cxx \
+ *.cpp \
+ *.c++ \
+ *.d \
+ *.java \
+ *.ii \
+ *.ixx \
+ *.ipp \
+ *.i++ \
+ *.inl \
+ *.h \
+ *.hh \
+ *.hxx \
+ *.hpp \
+ *.h++ \
+ *.idl \
+ *.odl \
+ *.cs \
+ *.php \
+ *.php3 \
+ *.inc \
+ *.m \
+ *.markdown \
+ *.md \
+ *.mm \
+ *.dox \
+ *.py \
+ *.f90 \
+ *.f \
+ *.for \
+ *.vhd \
+ *.vhdl \
+ *.txt
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH = img
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = html/footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax. However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvantages are that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = NO
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# managable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
# with spaces.
INPUT = . \
- ../include/OCApi.h \
- ../include/OCPlatform.h \
- ../include/OCRepresentation.h \
- ../include/OCResourceRequest.h \
- ../include/OCResourceResponse.h \
- ../include/OCResource.h \
- ../include/OCProvisioningManager.h \
- ../csdk/stack/include/octypes.h \
- ../csdk/stack/include/ocstackconfig.h \
+ ../../include/OCApi.h \
+ ../../include/OCPlatform.h \
+ ../../include/OCRepresentation.h \
+ ../../include/OCResourceRequest.h \
+ ../../include/OCResourceResponse.h \
+ ../../include/OCResource.h \
+ ../../include/OCProvisioningManager.h \
+ ../../csdk/stack/include/octypes.h \
+ ../../csdk/stack/include/ocstackconfig.h \
guides \
- ../../service/resource-encapsulation/include \
- ../../service/resource-hosting/include \
- ../../service/resource-container/include \
- ../../service/resource-container/bundle-api/include \
- ../../service/things-manager/sdk/inc/ThingsConfiguration.h \
- ../../service/things-manager/sdk/inc/ThingsMaintenance.h \
- ../../service/easy-setup/mediator/richsdk/inc/ \
- ../../service/easy-setup/enrollee/inc \
- ../../service/easy-setup/enrollee/src/softap.h \
- ../../service/easy-setup/inc \
- ../../service/resource-directory/include \
- ../../service/scene-manager/include \
-
+ ../../../service/resource-encapsulation/include \
+ ../../../service/resource-hosting/include \
+ ../../../service/resource-container/include \
+ ../../../service/resource-container/bundle-api/include \
+ ../../../service/things-manager/sdk/inc/ThingsConfiguration.h \
+ ../../../service/things-manager/sdk/inc/ThingsMaintenance.h \
+ ../../../service/easy-setup/mediator/richsdk/inc/ \
+ ../../../service/easy-setup/inc \
+ ../../../service/scene-manager/include \
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
--- /dev/null
+# Doxyfile 1.8.8
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = "IoTivity Internals Documentation"
+PROJECT_NUMBER =
+PROJECT_BRIEF =
+PROJECT_LOGO =
+OUTPUT_DIRECTORY = devdocs
+CREATE_SUBDIRS = NO
+ALLOW_UNICODE_NAMES = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF =
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = NO
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = YES
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 4
+ALIASES =
+TCL_SUBST =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING =
+MARKDOWN_SUPPORT = YES
+AUTOLINK_SUPPORT = YES
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+SUBGROUPING = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS = NO
+TYPEDEF_HIDES_STRUCT = NO
+LOOKUP_CACHE_SIZE = 0
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL = YES
+EXTRACT_PRIVATE = YES
+EXTRACT_PACKAGE = YES
+EXTRACT_STATIC = YES
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = YES
+CASE_SENSE_NAMES = YES
+HIDE_SCOPE_NAMES = NO
+SHOW_INCLUDE_FILES = YES
+SHOW_GROUPED_MEMB_INC = NO
+FORCE_LOCAL_INCLUDES = NO
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+STRICT_PROTO_MATCHING = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_FILES = YES
+SHOW_NAMESPACES = YES
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+CITE_BIB_FILES =
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET = NO
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT = devdox \
+ ../include \
+ ../src \
+ ../csdk/connectivity/api \
+ ../csdk/connectivity/common/inc \
+ ../csdk/connectivity/common/src \
+ ../csdk/connectivity/inc \
+ ../csdk/connectivity/src \
+ ../csdk/logger/include \
+ ../csdk/logger/src \
+ ../csdk/ocrandom/include \
+ ../csdk/ocrandom/src \
+ ../csdk/security/include \
+ ../csdk/security/src \
+ ../csdk/stack/include \
+ ../csdk/stack/src \
+ ../c_common/oic_malloc/include \
+ ../c_common/oic_malloc/src \
+ ../c_common/oic_string/include \
+ ../c_common/oic_string/src
+
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS =
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS =
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+REFERENCES_LINK_SOURCE = YES
+SOURCE_TOOLTIPS = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+CLANG_ASSISTED_PARSING = NO
+CLANG_OPTIONS =
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_EXTRA_STYLESHEET =
+HTML_EXTRA_FILES =
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+HTML_TIMESTAMP = YES
+HTML_DYNAMIC_SECTIONS = NO
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET = NO
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME = Publisher
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = NO
+QCH_FILE =
+QHP_NAMESPACE = org.doxygen.Project
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+GENERATE_ECLIPSEHELP = NO
+ECLIPSE_DOC_ID = org.doxygen.Project
+DISABLE_INDEX = NO
+GENERATE_TREEVIEW = NO
+ENUM_VALUES_PER_LINE = 4
+TREEVIEW_WIDTH = 250
+EXT_LINKS_IN_WINDOW = NO
+FORMULA_FONTSIZE = 10
+FORMULA_TRANSPARENT = YES
+USE_MATHJAX = NO
+MATHJAX_FORMAT = HTML-CSS
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS =
+MATHJAX_CODEFILE =
+SEARCHENGINE = YES
+SERVER_BASED_SEARCH = NO
+EXTERNAL_SEARCH = NO
+SEARCHENGINE_URL =
+SEARCHDATA_FILE = searchdata.xml
+EXTERNAL_SEARCH_ID =
+EXTRA_SEARCH_MAPPINGS =
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX = YES
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+MAKEINDEX_CMD_NAME = makeindex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4
+EXTRA_PACKAGES =
+LATEX_HEADER =
+LATEX_FOOTER =
+LATEX_EXTRA_FILES =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+LATEX_SOURCE_CODE = NO
+LATEX_BIB_STYLE = plain
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_SUBDIR =
+MAN_LINKS = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_PROGRAMLISTING = YES
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+GENERATE_DOCBOOK = NO
+DOCBOOK_OUTPUT = docbook
+DOCBOOK_PROGRAMLISTING = NO
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF = NO
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED =
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+EXTERNAL_PAGES = YES
+PERL_PATH = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS = YES
+MSCGEN_PATH =
+DIA_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = YES
+DOT_NUM_THREADS = 0
+DOT_FONTNAME = Helvetica
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+UML_LIMIT_NUM_FIELDS = 10
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+INTERACTIVE_SVG = NO
+DOT_PATH =
+DOTFILE_DIRS = devdox/dot
+MSCFILE_DIRS =
+DIAFILE_DIRS =
+PLANTUML_JAR_PATH =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+@page ca_functional CA Functional design/implementation
+
+- @ref caf_overview
+ - @ref caf_ovr_communication
+ - @ref caf_ovr_comm_netinterface
+ - @ref caf_ovr_comm_netinterface_msg
+ - @ref caf_ovr_comm_netinterface_control
+ - @ref caf_ovr_comm_netinterface_eth
+ - @ref caf_ovr_comm_netinterface_wifi
+ - @ref caf_ovr_comm_netinterface_edr
+ - @ref caf_ovr_comm_netinterface_le
+ - @ref caf_ovr_comm_netinterface_detail
+
+<hr>
+
+@section caf_overview Overview
+
+The following are assorted implementation notes/references in regards to
+@ref ca_overview
+
+@subsection caf_ovr_communication Communication Adapters
+
+@subsubsection caf_ovr_comm_netinterface Network Interface Creation
+
+Interface connections are created at program startup. A Message Handler is
+started by invoking the CAInitialize() command. This in turn establishes
+the needed data structures and callbacks.
+
+@dotfile ca_arch_sketch.gv
+
+@paragraph caf_ovr_comm_netinterface_msg Message Handler
+
+The message handler owns athread pool and send and reive queue.
+
+@paragraph caf_ovr_comm_netinterface_control Interface controller
+
+This directly controls the individual adapters. Calling CAInitializeAdapters(ca_thread_pool_t handle)
+will invoke whatever config had been established by compile-time flags.
+
+@paragraph caf_ovr_comm_netinterface_eth Ethernet Adapter
+
+An interface adapter implemented to support Ethernet connections. It is
+created by calling CAInitializeEthernet()
+
+@paragraph caf_ovr_comm_netinterface_wifi WiFi Adapter
+
+An interface adapter implemented to support WiFi connections. It is created
+by calling CAInitializeWifi()
+
+@paragraph caf_ovr_comm_netinterface_edr EDR Adapter
+
+An interface adapter implemented to support EDR connections. It is created
+by calling CAInitializeEDR()
+
+@paragraph caf_ovr_comm_netinterface_le LE Adapter
+
+An interface adapter implemented to support LE connections. It is created
+by calling CAInitializeLE()
+
+@paragraph caf_ovr_comm_netinterface_detail Detailed Structure
+
+The following is a more detailed breakdown on the main types involved.
+Several structs and function details are present. However the diagram
+is more of a sketch and is not 100% complete.
+
+@dotfile ca_arch.gv
+
+*/
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+@page ca_overview CA Overview
+
+- @ref cao_overview
+- @ref cao_ddoc
+ - @ref cao_ddoc_freqs
+ - @ref cao_ddoc_freqs_discovery
+ - @ref cao_ddoc_fr1101
+ - @ref cao_ddoc_fr1102
+ - @ref cao_ddoc_fr1103
+ - @ref cao_ddoc_fr1104
+ - @ref cao_ddoc_fr1105
+ - @ref cao_ddoc_fr1106
+ - @ref cao_ddoc_fr1107
+ - @ref cao_ddoc_fr1108
+ - @ref cao_ddoc_fr1109
+ - @ref cao_ddoc_freqs_msg
+ - @ref cao_ddoc_fr1201
+ - @ref cao_ddoc_fr1202
+ - @ref cao_ddoc_fr1203
+ - @ref cao_ddoc_fr1204
+ - @ref cao_ddoc_freqs_obs
+ - @ref cao_ddoc_fr1301
+ - @ref cao_ddoc_fr1302
+ - @ref cao_ddoc_fr1303
+ - @ref cao_ddoc_fr1304
+ - @ref cao_ddoc_freqs_netconfig
+ - @ref cao_ddoc_fr1401
+ - @ref cao_ddoc_fr1402
+ - @ref cao_ddoc_fr1403
+ - @ref cao_ddoc_freqs_control_ip
+ - @ref cao_ddoc_fr2101
+ - @ref cao_ddoc_fr2102
+ - @ref cao_ddoc_fr2103
+ - @ref cao_ddoc_fr2104
+ - @ref cao_ddoc_fr2105
+ - @ref cao_ddoc_fr2106
+ - @ref cao_ddoc_freqs_control_bt
+ - @ref cao_ddoc_fr2201
+ - @ref cao_ddoc_fr2202
+ - @ref cao_ddoc_fr2203
+ - @ref cao_ddoc_fr2204
+ - @ref cao_ddoc_fr2205
+ - @ref cao_ddoc_fr2206
+ - @ref cao_ddoc_freqs_control_ble
+ - @ref cao_ddoc_fr2301
+ - @ref cao_ddoc_fr2302
+ - @ref cao_ddoc_fr2303
+ - @ref cao_ddoc_fr2304
+ - @ref cao_ddoc_fr2305
+ - @ref cao_ddoc_fr2306
+ - @ref cao_ddoc_fr2307
+ - @ref cao_ddoc_freqs_control_zigbee
+ - @ref cao_ddoc_fr2401
+ - @ref cao_ddoc_fr2402
+ - @ref cao_ddoc_fr2403
+ - @ref cao_ddoc_fr2404
+ - @ref cao_ddoc_fr2405
+ - @ref cao_ddoc_fr2406
+ - @ref cao_ddoc_freqs_control_zwave
+ - @ref cao_ddoc_fr2501
+ - @ref cao_ddoc_fr2502
+ - @ref cao_ddoc_fr2503
+ - @ref cao_ddoc_fr2504
+ - @ref cao_ddoc_fr2505
+ - @ref cao_ddoc_fr2506
+ - @ref cao_ddoc_qattr
+ - @ref cao_ddoc_qattr_reliability
+ - @ref cao_ddoc_nfr201
+ - @ref cao_ddoc_nfr202
+ - @ref cao_ddoc_qattr_security
+ - @ref cao_ddoc_nfr301
+ - @ref cao_ddoc_nfr302
+ - @ref cao_ddoc_qattr_maintenance
+ - @ref cao_ddoc_nfr501
+ - @ref cao_ddoc_qattr_portability
+ - @ref cao_ddoc_nfr601
+ - @ref cao_ddoc_nfr602
+ - @ref cao_ddoc_nfr603
+ - @ref cao_ddoc_nfr604
+ - @ref cao_ddoc_nfr605
+ - @ref cao_ddoc_qattr_extensibility
+ - @ref cao_ddoc_nfr701
+ - @ref cao_ddoc_constraints
+ - @ref cao_ddoc_constraints_licence
+ - @ref cao_ddoc_con101
+<hr>
+
+@section cao_overview Overview
+
+The original Connectivity Abstraction design overview diagram was from a presentation format. A similar version has been recreated in dot.
+
+@dotfile ca_overview.gv
+
+
+@section cao_ddoc Design doc info
+
+
+@subsection cao_ddoc_freqs Functional Requirements
+
+
+@subsubsection cao_ddoc_freqs_discovery Discovery
+
+
+@paragraph cao_ddoc_fr1101 FR.1101
+Client can find all resources on the reachable networks.
+- CA should provide the way to discover all resources on the WiFi/Ethernet/BLE/BT network.
+- Resources should be represented by dedicated URI.
+- Add ZigBee and ZWave to supported network. ( 2015.01 ) : TBD
+
+@paragraph cao_ddoc_fr1102 FR.1102
+Client can find all resources on the specific network.
+- CA should provide the way to discover all resources on the specified network.
+- The specified network can be the one of or those of WiFi/Ethernet/BLE/BT network.
+- Resources should be represented by dedicated URI.
+- Add ZigBee and ZWave to supported network. ( 2015.01 ) : TBD
+
+@paragraph cao_ddoc_fr1103 FR.1103
+Client can find specific resource on the reachable networks.
+- CA should provide discovery method to find specific resource on the WiFi/Ethernet/BLE/BT network.
+- Resource should be represented by URI.
+- Add ZigBee and ZWave to supported network. ( 2015.01 ) : TBD
+
+@paragraph cao_ddoc_fr1104 FR.1104
+Client can find specific resource on the specific network.
+- CA should provide discovery method to find specific resource on the specific network.
+- The specified network can be the one of or those of WiFi/Ethernet/BLE/BT network.
+- Resources should be represented by dedicated URI.
+- Add ZigBee and ZWave to supported network. ( 2015.01 ) : TBD
+
+@paragraph cao_ddoc_fr1105 FR.1105
+Server can advertise single resource on the reachable network.
+- CA should provide advertising method to notify the resource on the WiFi/Ethernet/BLE/BT network.
+- Resource should be represented by URI
+- Advertising can include 'alive' or 'disappear'.
+- Add ZigBee and ZWave to supported network. ( 2015.01 ) : TBD
+
+@paragraph cao_ddoc_fr1106 FR.1106
+Server can advertise single resource on the specific network.
+- CA should provide advertising method to notify the resource on the specified network.
+- The spefied network can be the on of or those of WiFi/Ethernet/BLE/BT network
+- Resource should be represented by URI
+- Advertising can include 'alive' or 'disappear'.
+- Add ZigBee and ZWave to supported network. ( 2015.01 ) : TBD
+
+@paragraph cao_ddoc_fr1107 FR.1107
+Server can advertise all resources at a time on the reachable network.
+- CA should provide advertising method to notify the all resources on the WiFi/Ethernet/BLE/BT network.
+- Resource should be represented by URI
+- Advertising can include 'alive' or 'disappear'.
+- Add ZigBee and ZWave to supported network. ( 2015.01 ) : TBD
+
+@paragraph cao_ddoc_fr1108 FR.1108
+Server can advertise all resource at a time on the specific network.
+- CA should provide advertising method to notify the all resources on the specified network.
+- The spefied network can be the on of or those of WiFi/Ethernet/BLE/BT network
+- Resource should be represented by URI
+- Advertising can include 'alive' or 'disappear'.
+- Add ZigBee and ZWave to supported network. ( 2015.01 ) : TBD
+
+@paragraph cao_ddoc_fr1109 FR.1109
+Client can send periodic hearbeat request on the specific resource.
+- CA should check the status of discovered resource periodically.
+- Heartbeat policy can be followed by IoTivity specification.
+
+
+@subsubsection cao_ddoc_freqs_msg Messaging
+
+
+@paragraph cao_ddoc_fr1201 FR.1201
+Client can send request message to server
+- CA should provide the way to send request message to server on the supported network.
+- CA should notify the event to server when the request message arrives from client.
+
+@paragraph cao_ddoc_fr1202 FR.1202
+Server can send response message to client
+- CA should provide the way to send response messate to client on the supported network.
+- CA should notify the event to client when the response message arrives from server.
+
+@paragraph cao_ddoc_fr1203 FR.1203
+Client and Server can select QoS level for each message
+- CA should provide the way to select message QoS level to the server and client.
+- QoS level policy can follow CoAP guideline ( CON / NON / ACK / RESET )
+
+@paragraph cao_ddoc_fr1204 FR.1204
+Message can be re-sent if acknowledgement didn't received.
+- CA should send high QoS level message repeatly until the acknowledgement arrive.
+- Retransmission policy can follows CoAP guideline.
+
+
+@subsubsection cao_ddoc_freqs_obs Observation
+
+
+@paragraph cao_ddoc_fr1301 FR.1301
+Client can send observation request message to server
+- CA should provide the way to send observation request message to server on the supported network.
+
+@paragraph cao_ddoc_fr1302 FR.1302
+Server can send observation message
+- CA should provider the way to send observation event to the clients which request observation on the supported network.
+
+@paragraph cao_ddoc_fr1303 FR.1303
+Client can send observation cancel request message to server
+- CA should provide the way to send observation cancel request message to server on the supported network.
+
+@paragraph cao_ddoc_fr1304 FR.1304
+Server can cancel observation
+- CA should provide the way to send observation cancel event to the clients which request observation on the supported network.
+
+
+@subsubsection cao_ddoc_freqs_netconfig Network Configuration
+
+
+@paragraph cao_ddoc_fr1401 FR.1401
+Server / Client can select the network interfaces to use.
+- CA should provide the way to select network interfaces to use for communication.
+
+@paragraph cao_ddoc_fr1402 FR.1402
+Server / Client can unselect the network interfaces
+- CA should provide the way to unselect network interfaces to use for communication.
+
+@paragraph cao_ddoc_fr1403 FR.1403
+Server / Client can receive the status changes of network interface
+- CA should notify whenever the network interface status changes.
+
+
+@subsubsection cao_ddoc_freqs_control_ip Connectivity Control - Wifi/Ethernet
+
+
+@paragraph cao_ddoc_fr2101 FR.2101
+Server / client can listen multicast message
+- CA should bind multicast port
+- Multicast IP address and port policy can be followed by IoTivity specification.
+
+@paragraph cao_ddoc_fr2102 FR.2102
+Server / client can send multicast message
+- CA should bind multicast port
+- Multicast IP address and port policy can be followed by IoTivity specification.
+
+@paragraph cao_ddoc_fr2103 FR.2103
+Serve / client can listen unicast message
+- CA should bind unicast port
+- Unicast IP address and port policy can be followed by IoTivity specification.
+
+@paragraph cao_ddoc_fr2104 FR.2104
+Server / client can send unicast message
+- CA should bind unicast port
+- Unicast IP address and port policy can be followed by IoTivity specification.
+
+@paragraph cao_ddoc_fr2105 FR.2105
+Server / client can monitor the interface status.
+- CA should notify the status of interface whenever change the status
+
+@paragraph cao_ddoc_fr2106 FR.2106
+Server / client can communicate in secured way
+- CA should provde the way to send / receive data in secure way
+- DTLS should be supported as a secure transfer
+
+
+@subsubsection cao_ddoc_freqs_control_bt Connectivity Control - Bluetooth
+
+
+@paragraph cao_ddoc_fr2201 FR.2201
+Client can discover the device has IoTivity server when inquiry time.
+- CA should scan the device using the specific UUID.
+- The specific UUID should represent IoTivity service and be unique
+
+@paragraph cao_ddoc_fr2202 FR.2202
+Server can register IoTivity service which can be found when inquiry scan time
+- CA should register the specific UUID to BT service.
+- The specific UUID should represent IoTivity service and be unique
+
+@paragraph cao_ddoc_fr2203 FR.2203
+Client can request bonding to the device has IoTivity server.
+- CA should request bonding to the device.
+- CA should delegate the bonding procedure to the platform
+
+@paragraph cao_ddoc_fr2204 FR.2204
+Server can accept / deny the bonding request from client device
+- CA should deletage the bonding procedure to the platform
+
+@paragraph cao_ddoc_fr2205 FR.2205
+Server / client can get the bonded device list from BT service
+
+@paragraph cao_ddoc_fr2206 FR.2206
+Server / client can communicate throuth the RFCOMM
+- Serial Port Profile( SPP ) should be provided by platform.
+- Platform should provide the fundamental operation functions to CA.
+ : connect(), accept(), disconnect(), send(), recv()
+
+@subsubsection cao_ddoc_freqs_control_ble Connectivity Control - BLE
+
+
+@paragraph cao_ddoc_fr2301 FR.2301
+Client can discover the device has IoTivity server when scan time.
+- CA should scan the device using the specific UUID
+- The specific UUID should represent IoTivity service ahd be unique
+
+@paragraph cao_ddoc_fr2302 FR.2302
+Server can register IoTivity service which can be found when
+advertising time
+- CA should register the specific UUID to BT service.
+- The specific UUID should represent IoTivity service and be unique
+
+@paragraph cao_ddoc_fr2303 FR.2303
+Client can request bonding to the device has IoTivity server.
+- CA should request bonding to the device.
+- CA should delegate the bonding procedure to the platform
+
+@paragraph cao_ddoc_fr2304 FR.2304
+Server can accept / deny the bonding request from client device
+- CA should deletage the bonding procedure to the platform
+
+@paragraph cao_ddoc_fr2305 FR.2305
+Server / client can get the bonded device list from BT service
+
+@paragraph cao_ddoc_fr2306 FR.2306
+Server / client can communicate throuth the RFCOMM
+- General Attribute Profile( GATT ) should be provided by platform.
+- Platform should provide the fundamental operation functions to CA.
+ : connect(), accept(), disconnect(), send(), recv()
+
+@paragraph cao_ddoc_fr2307 FR.2307
+Server / client can send more lager data than 23 bytes
+- (Optional) Platform may provide 'read long' and 'write long' feature of BLE
+- CA should fragment and reassemble the lager data
+
+
+@subsubsection cao_ddoc_freqs_control_zigbee Connectivity Control - ZigBee
+
+
+@paragraph cao_ddoc_fr2401 FR.2401
+Client can start forming the ZigBee network
+- Client means ZigBee coordinator device
+- ZigBee service should provide the way to start ZigBee network forming
+
+@paragraph cao_ddoc_fr2402 FR.2402
+Client can finish the formed ZigBee network
+- Client means ZigBee coordinator device
+- ZigBee service should provide the way to finish ZigBee network forming
+
+@paragraph cao_ddoc_fr2403 FR.2403
+Client can receive the event whenever the ZigBee end-device joins and leaves
+- CA should know the identifier of ZigBee end-device when joins and leaves.
+- CA should know the identifier of ZigBee end-device joined through ZigBee router when joins and leaves.
+- CA could select the ZigBee end-device to join
+
+@paragraph cao_ddoc_fr2404 FR.2404
+Client can convert common ZigBee cluster to IoTivity URI.
+- CA should convert the common ZigBee cluster to URI.
+- The common ZigBee cluster can be one of the clusters announced by ZigBee alliance.
+ : eg. Home Automation Profile, Smart Energy Profile, and so on.
+
+@paragraph cao_ddoc_fr2405 FR.2405
+Client can convert common ZigBee cluster attributes to IoTivity attributes
+- CA should convert the common ZigBee cluster to attribute of the URI.
+- The common ZigBee profile can be one of the clusters announced by ZigBee alliance.
+
+@paragraph cao_ddoc_fr2406 FR.2406
+Client can convert CoAP message to ZCL command
+- CA should convert CoAP message to ZCL command to send ZigBee end-device
+
+
+@subsubsection cao_ddoc_freqs_control_zwave Connectivity Control - ZWave
+
+
+@paragraph cao_ddoc_fr2501 FR.2501
+Client can start creating PAN ( ZWave network )
+- Client means ZWave controller device
+- ZWave service should provide the way to start ZWave network creation
+
+@paragraph cao_ddoc_fr2502 FR.2502
+Client can finish the created PAN ( ZWave network )
+- Client means ZWave controller device
+- ZWave service should provide the way to finish created ZWave network
+
+@paragraph cao_ddoc_fr2503 FR.2503
+Client can receive the event whenever the ZWave slave joins and leaves
+- CA should know the identifier of ZWave slave when joins and leaves.
+- CA should know the identifier of ZWave slave joined through ZWave router when joins and leaves.
+- CA could select the ZWave slave to join
+
+@paragraph cao_ddoc_fr2504 FR.2504
+Client can convert common ZWave device class to IoTivity URI
+- CA should convert the common ZWave device class to URI.
+- The common ZWave device class can be one of the device classes announced by ZWave alliance.
+
+@paragraph cao_ddoc_fr2505 FR.2505
+Client can convert common ZWave command class to IoTivity attribute
+- CA should convert the common ZWave command class to attribute of the URI.
+- The common ZWave command class can be one of the command classes announced by ZWave alliance.
+
+@paragraph cao_ddoc_fr2506 FR.2506
+Client can convert CoAP message to ZWave command
+- CA should convert CoAP message to command class to send ZWave slave
+
+
+@subsection cao_ddoc_qattr Quality Attributes
+
+
+@subsubsection cao_ddoc_qattr_reliability Reliability
+
+
+@paragraph cao_ddoc_nfr201 NFR.201
+Network availability detection
+- Maxinum number of messaging failure is 3 during 10 minutes in available network .
+- Terminate the connection when the number is over the maximum value.
+
+@paragraph cao_ddoc_nfr202 NFR.202
+Messaging
+- The transmitted message from source has to be deliverd to the destination completely.
+
+@subsubsection cao_ddoc_qattr_security Security
+
+
+@paragraph cao_ddoc_nfr301 NFR.301
+Transfer Channel Protection
+- should protect the transfer channel using DTLS in CoaP , authentication in BT and other mechanisms in connectivities
+
+@paragraph cao_ddoc_nfr302 NFR.302
+Message Protection ( TBD )
+- should be able to encrypt the message to protect using RSA??
+
+
+@subsubsection cao_ddoc_qattr_maintenance Maintenance
+
+
+@paragraph cao_ddoc_nfr501 NFR.501
+Modularization for connectivities
+- One connectivity module change shouldn't have an effect on the other connectivity module.
+
+@subsubsection cao_ddoc_qattr_portability Portability
+
+
+@paragraph cao_ddoc_nfr601 NFR.601
+Support on Ubuntu 12.04
+- The software should be ported on Ubuntu (12.04) without change.
+- The platform specific portion should be controlled by build configurations.
+
+@paragraph cao_ddoc_nfr602 NFR.602
+Support on Android 4.4 / 5.0 and higher
+- The software should be ported on Android v5.0 and higher without change.
+- The platform specific portion should be controlled by build configurations.
+- JNI block can be added
+
+@paragraph cao_ddoc_nfr603 NFR.603
+Support on Tizen v2.3 and higher
+- The software should be ported on Tizen v2.3 and higher without change.
+- The platform specific portion should be controlled by build configurations.
+
+@paragraph cao_ddoc_nfr604 NFR.604
+Support on Arduino Mega
+- The software should be ported on Arduino Mega without change.
+- Connectivity function can be supported through the various shields.
+- The platform specific portion should be controlled by build configurations.
+
+@paragraph cao_ddoc_nfr605 NFR.605
+Support on Arduino Due
+- The software should be ported on Arduino Due without change.
+- Connectivity function can be supported through the various shields.
+- The platform specific portion should be controlled by build configurations.
+
+
+@subsubsection cao_ddoc_qattr_extensibility Extensibility
+
+@paragraph cao_ddoc_nfr701 NFR.701
+Connectivity Extension
+- The Architecture change has to be minimized when expanding Connectivities.
+
+
+@subsection cao_ddoc_constraints Constraints
+
+
+@subsubsection cao_ddoc_constraints_licence License
+
+
+@paragraph cao_ddoc_con101 CON.101
+Open source license
+- All source codes should be released under Apache License v2 or compatible.
+
+*/
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+digraph G {
+ label = "Network Interface Creation";
+ fontsize = 10;
+
+ edge [
+ fontsize = 10
+ ]
+
+ node [
+ fontsize = 10,
+ ]
+
+ // ----
+
+ msg_handler [
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td port="a" tooltip="Message Handler" bgcolor="gray">Message Handler</td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref g_threadPoolHandle" tooltip="-g_threadPoolHandle: ca_thread_pool_t">-g_threadPoolHandle: ca_thread_pool_t</td></tr>
+ <tr><td align="left" href="\ref g_sendThread" tooltip="-g_sendThread: CAQueueingThread_t">-g_sendThread: CAQueueingThread_t</td></tr>
+ <tr><td align="left" href="\ref g_receiveThread" tooltip="-g_receiveThread: CAQueueingThread_t">-g_receiveThread: CAQueueingThread_t</td></tr>
+ <tr><td align="left" href="\ref g_retransmissionContext" tooltip="-g_retransmissionContext: CARetransmission_t">-g_retransmissionContext: CARetransmission_t</td></tr>
+ <tr><td align="left" href="\ref g_requestHandler" tooltip="-g_requestHandler: CARequestCallback">-g_requestHandler: CARequestCallback</td></tr>
+ <tr><td align="left" href="\ref g_responseHandler" tooltip="-g_responseHandler: CAResponseCallback">-g_responseHandler: CAResponseCallback</td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CAInitializeMessageHandler()" tooltip="+CAInitializeMessageHandler">+CAInitializeMessageHandler</td></tr>
+ <tr><td align="left" href="\ref CATerminateMessageHandler()" tooltip="+CATerminateMessageHandler">+CATerminateMessageHandler</td></tr>
+ </table>>
+ ]
+
+ threadpool [
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref ca_thread_pool_t" tooltip="ca_threadpool_t" bgcolor="gray">ca_threadpool_t</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref ca_thread_pool_init()" tooltip="+ca_thread_pool_init">+ca_thread_pool_init</td></tr>
+ <tr><td align="left" href="\ref ca_thread_pool_free()" tooltip="+ca_thread_pool_free">+ca_thread_pool_free</td></tr>
+ <tr><td align="left" href="\ref ca_thread_pool_add_task()" tooltip="+ca_thread_pool_add_task">+ca_thread_pool_add_task</td></tr>
+ </table>>
+ ]
+
+
+ thread_out [
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CASendThreadProcess()" tooltip="Send Thread" bgcolor="gray">Send Thread</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CASendThreadProcess()" tooltip="+CASendThreadProcess">+CASendThreadProcess</td></tr>
+ </table>>
+ ]
+
+ thread_in [
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CAReceiveThreadProcess()" tooltip="Receive Thread" bgcolor="gray">Receive Thread</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CAReceiveThreadProcess()" tooltip="+CAReceiveThreadProcess">+CAReceiveThreadProcess</td></tr>
+ </table>>
+ ]
+
+ thread_retrans [
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CASendUnicastData()" tooltip="Retransmit Thread" bgcolor="gray">Retransmit Thread</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CASendUnicastData()" tooltip="+CASendUnicastData">+CASendUnicastData</td></tr>
+ </table>>
+ ]
+
+ control [
+ tooltip = "Interface Controller",
+ label = "{Interface Controller| +CAInitializeAdapters()\l\n \n }",
+ URL = "\ref CAInitializeAdapters()"
+
+
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CAInitializeAdapters()" tooltip="Interface Controller" bgcolor="gray">Interface Controller</td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref g_adapterHandler" tooltip="-g_adapterHandler: CAConnectivityHandler_t[]">-g_adapterHandler: CAConnectivityHandler_t[]</td></tr>
+ <tr><td align="left" href="\ref g_networkPacketReceivedCallback" tooltip="-g_networkPacketReceivedCallback: CANetworkPacketReceivedCallback">-g_networkPacketReceivedCallback: CANetworkPacketReceivedCallback</td></tr>
+
+ <tr><td align="left" href="\ref g_networkChangeCallback" tooltip="-g_networkChangeCallback: CANetworkChangeCallback">-g_networkChangeCallback: CANetworkChangeCallback</td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CAInitializeAdapters()" tooltip="+CAInitializeAdapters">+CAInitializeAdapters</td></tr>
+ <tr><td align="left" href="\ref CATerminateAdapters()" tooltip="+CATerminateAdapters">+CATerminateAdapters</td></tr>
+ <tr><td align="left" href="\ref CAStartAdapter()" tooltip="+CAStartAdapter">+CAStartAdapter</td></tr>
+ <tr><td align="left" href="\ref CAStopAdapter()" tooltip="+CAStopAdapter">+CAStopAdapter</td></tr>
+ <tr><td align="left" href="\ref CAGetNetworkInfo()" tooltip="+CAGetNetworkInfo">+CAGetNetworkInfo</td></tr>
+ <tr><td align="left" href="\ref CAStartListeningServerAdapters()" tooltip="+CAStartListeningServerAdapters">+CAStartListeningServerAdapters</td></tr>
+ <tr><td align="left" href="\ref CAStartDiscoveryServerAdapters()" tooltip="+CAStartDiscoveryServerAdapters">+CAStartDiscoveryServerAdapters</td></tr>
+ </table>>
+ ]
+
+
+ conn_handler [
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CAConnectivityHandler_t" tooltip="CAConnectivityHandler_t" bgcolor="gray">CAConnectivityHandler_t</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::startAdapter" tooltip="+startAdapter: CAAdapterStart">+startAdapter: CAAdapterStart</td></tr>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::startListenServer" tooltip="+startListenServer: CAAdapterStartListeningServer">+startListenServer: CAAdapterStartListeningServer</td></tr>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::startDiscoveryServer" tooltip="+startDiscoveryServer: CAAdapterStartDiscoveryServer">+startDiscoveryServer: CAAdapterStartDiscoveryServer</td></tr>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::sendData" tooltip="+sendData: CAAdapterSendUnicastData">+sendData: CAAdapterSendUnicastData</td></tr>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::sendDataToAll" tooltip="+sendDataToAll: CAAdapterSendMulticastData">+sendDataToAll: CAAdapterSendMulticastData</td></tr>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::GetnetInfo" tooltip="+GetnetInfo: CAAdapterGetNetworkInfo">+GetnetInfo: CAAdapterGetNetworkInfo</td></tr>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::readData" tooltip="+readData: CAAdapterReadData">+readData: CAAdapterReadData</td></tr>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::stopAdapter" tooltip="+stopAdapter: CAAdapterStop">+stopAdapter: CAAdapterStop</td></tr>
+ <tr><td align="left" href="\ref CAConnectivityHandler_t::terminate" tooltip="+terminate: CAAdapterTerminate">+terminate: CAAdapterTerminate</td></tr>
+ </table>>
+
+
+ ]
+
+ adapt01 [
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CAInitializeEthernet" tooltip="Ethernet Adapter" bgcolor="gray">Ethernet Adapter</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CAInitializeEthernet" tooltip="+CAInitializeEthernet">+CAInitializeEthernet</td></tr>
+ <tr><td align="left" href="\ref CATerminateEthernet()" tooltip="+CATerminateEthernet">+CATerminateEthernet</td></tr>
+ <tr><td align="left" href="\ref CAStartEthernet()" tooltip="+CAStartEthernet">+CAStartEthernet</td></tr>
+ <tr><td align="left" href="\ref CAStopEthernet()" tooltip="+CAStopEthernet">+CAStopEthernet</td></tr>
+ <tr><td align="left" href="\ref CAStartEthernetListeningServer()" tooltip="+CAStartEthernetListeningServer">+CAStartEthernetListeningServer</td></tr>
+ <tr><td align="left" href="\ref CAStartEthernetDiscoveryServer()" tooltip="+CAStartEthernetDiscoveryServer">+CAStartEthernetDiscoveryServer</td></tr>
+ <tr><td align="left" href="\ref CAGetEthernetInterfaceInformation" tooltip="+CAGetEthernetInterfaceInformation">+CAGetEthernetInterfaceInformation</td></tr>
+ <tr><td align="left" href="\ref CASendEthernetUnicastData()" tooltip="+CASendEthernetUnicastData">+CASendEthernetUnicastData</td></tr>
+ <tr><td align="left" href="\ref CASendEthernetMulticastData()" tooltip="+CASendEthernetMulticastData">+CASendEthernetMulticastData</td></tr>
+ <tr><td align="left" href="\ref CAReadEthernetData()" tooltip="+CAReadEthernetData">+CAReadEthernetData</td></tr>
+ </table>>
+ ]
+
+ adapt02 [
+ tooltip = "WiFi Adapter",
+ label = "{WiFi Adapter| +CAInitializeWifi()\l\n \n }",
+ URL = "\ref CAInitializeWifi()"
+
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CAInitializeWifi" tooltip="WiFi Adapter" bgcolor="gray">WiFi Adapter</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CAInitializeWifi()" tooltip="+CAInitializeWifi">+CAInitializeWifi</td></tr>
+ <tr><td align="left" href="\ref CATerminateWIFI()" tooltip="+CATerminateWIFI">+CATerminateWIFI</td></tr>
+ <tr><td align="left" href="\ref CAStartWIFI()" tooltip="+CAStartWIFI">+CAStartWIFI</td></tr>
+ <tr><td align="left" href="\ref CAStopWIFI()" tooltip="+CAStopWIFI">+CAStopWIFI</td></tr>
+ <tr><td align="left" href="\ref CAStartWIFIListeningServer()" tooltip="+CAStartWIFIListeningServer">+CAStartWIFIListeningServer</td></tr>
+ <tr><td align="left" href="\ref CAStartWIFIDiscoveryServer()" tooltip="+CAStartWIFIDiscoveryServer">+CAStartWIFIDiscoveryServer</td></tr>
+ <tr><td align="left" href="\ref CAGetWIFIInterfaceInformation()" tooltip="+CAGetWIFIInterfaceInformation">+CAGetWIFIInterfaceInformation</td></tr>
+ <tr><td align="left" href="\ref CASendWIFIUnicastData()" tooltip="+CASendWIFIUnicastData">+CASendWIFIUnicastData</td></tr>
+ <tr><td align="left" href="\ref CASendWIFIMulticastData()" tooltip="+CASendWIFIMulticastData">+CASendWIFIMulticastData</td></tr>
+ <tr><td align="left" href="\ref CAReadWIFIData()" tooltip="+CAReadWIFIData">+CAReadWIFIData</td></tr>
+ </table>>
+ ]
+
+ adapt03 [
+ tooltip = "EDR Adapter",
+ label = "{EDR Adapter| +CAInitializeEDR()\l\n \n }",
+ URL = "\ref CAInitializeEDR()"
+
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CAInitializeEDR" tooltip="EDR Adapter" bgcolor="gray">EDR Adapter</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CAInitializeEDR" tooltip="+CAInitializeEDR">+CAInitializeEDR</td></tr>
+ <tr><td align="left" href="\ref CATerminateEDR()" tooltip="+CATerminateEDR">+CATerminateEDR</td></tr>
+ <tr><td align="left" href="\ref CAStartEDR()" tooltip="+CAStartEDR">+CAStartEDR</td></tr>
+ <tr><td align="left" href="\ref CAStopEDR()" tooltip="+CAStopEDR">+CAStopEDR</td></tr>
+ <tr><td align="left" href="\ref CAStartEDRListeningServer()" tooltip="+CAStartEDRListeningServer">+CAStartEDRListeningServer</td></tr>
+ <tr><td align="left" href="\ref CAStartEDRDiscoveryServer()" tooltip="+CAStartEDRDiscoveryServer">+CAStartEDRDiscoveryServer</td></tr>
+ <tr><td align="left" href="\ref CAGetEDRInterfaceInformation" tooltip="+CAGetEDRInterfaceInformation">+CAGetEDRInterfaceInformation</td></tr>
+ <tr><td align="left" href="\ref CASendEDRUnicastData()" tooltip="+CASendEDRUnicastData">+CASendEDRUnicastData</td></tr>
+ <tr><td align="left" href="\ref CASendEDRMulticastData()" tooltip="+CASendEDRMulticastData">+CASendEDRMulticastData</td></tr>
+ <tr><td align="left" href="\ref CAReadEDRData()" tooltip="+CAReadEDRData">+CAReadEDRData</td></tr>
+ </table>>
+ ]
+
+ adapt04 [
+ tooltip = "LE Adapter",
+ label = "{LE Adapter| +CAInitializeLE()\l\n \n }",
+ URL = "\ref CAInitializeLE()"
+
+ shape = none
+ margin = 0
+ label = <<table border="1" cellspacing="0" cellborder="0">
+ <tr><td href="\ref CAInitializeLE" tooltip="LE Adapter" bgcolor="gray">LE Adapter</td></tr>
+ <hr/>
+ <tr><td> </td></tr>
+ <hr/>
+ <tr><td align="left" href="\ref CAInitializeLE()" tooltip="+CAInitializeLE">+CAInitializeLE</td></tr>
+ <tr><td align="left" href="\ref CATerminateLE()" tooltip="+CATerminateLE">+CATerminateLE</td></tr>
+ <tr><td align="left" href="\ref CAStartLE()" tooltip="+CAStartLE">+CAStartLE</td></tr>
+ <tr><td align="left" href="\ref CAStopLE" tooltip="+CAStopLE">+CAStopLE</td></tr>
+ <tr><td align="left" href="\ref CAStartLEListeningServer()" tooltip="+CAStartLEListeningServer">+CAStartLEListeningServer</td></tr>
+ <tr><td align="left" href="\ref CAStartLEDiscoveryServer()" tooltip="+CAStartLEDiscoveryServer">+CAStartLEDiscoveryServer</td></tr>
+ <tr><td align="left" href="\ref CAGetLEInterfaceInformation()" tooltip="+CAGetLEInterfaceInformation">+CAGetLEInterfaceInformation</td></tr>
+ <tr><td align="left" href="\ref CASendLEUnicastData()" tooltip="+CASendLEUnicastData">+CASendLEUnicastData</td></tr>
+ <tr><td align="left" href="\ref CASendLEMulticastData()" tooltip="+CASendLEMulticastData">+CASendLEMulticastData</td></tr>
+ <tr><td align="left" href="\ref CAReadLEData()" tooltip="+CAReadLEData">+CAReadLEData</td></tr>
+ </table>>
+ ]
+
+
+ // UML Inheritance relationships
+ edge [
+ arrowtail = open,
+ dir = back
+ ]
+
+ {
+ conn_handler -> adapt01
+ conn_handler -> adapt02
+ conn_handler -> adapt03
+ conn_handler -> adapt04
+ }
+
+ // UML Aggregation relationships
+ edge [
+ arrowtail = odiamond,
+ dir = back
+ ]
+
+ msg_handler -> control
+ msg_handler -> threadpool
+ msg_handler -> thread_out
+ msg_handler -> thread_in
+ msg_handler -> thread_retrans
+ control -> conn_handler
+
+
+ // Additional 'layout' tweaks
+ {rank = same control threadpool thread_out thread_in thread_retrans}
+ edge [
+ style = invis
+ ]
+ threadpool -> thread_out -> control -> thread_in -> thread_retrans
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+digraph G {
+ label = "Network Interface Creation";
+ fontsize = 10;
+
+ edge [
+ fontsize = 10
+ ]
+
+ node [
+ fontsize = 10,
+ shape = "record"
+ ]
+
+ // ----
+
+ msg_handler [
+ label = "{Message Handler| | }",
+ tooltip = "Message Handler",
+ URL = "\ref caf_ovr_comm_netinterface_msg"
+ ]
+
+ control [
+ label = "{Interface controller| | }",
+ tooltip = "Interface controller",
+ URL = "\ref caf_ovr_comm_netinterface_control"
+ ]
+
+ adapt01 [
+ label = "{Ethernet Adapter| | }",
+ tooltip = "Ethernet Adapter",
+ URL = "\ref caf_ovr_comm_netinterface_eth"
+ ]
+
+ adapt02 [
+ label = "{WiFi Adapter| | }",
+ tooltip = "WiFi Adapter",
+ URL = "\ref caf_ovr_comm_netinterface_wifi"
+ ]
+
+ adapt03 [
+ label = "{EDR Adapter| | }",
+ tooltip = "EDR Adapter",
+ URL = "\ref caf_ovr_comm_netinterface_edr"
+ ]
+
+ adapt04 [
+ label = "{LE Adapter| | }"
+ tooltip = "LE Adapter",
+ URL = "\ref caf_ovr_comm_netinterface_le"
+ ]
+
+ // UML Aggregation relationships
+ edge [
+ arrowtail = odiamond,
+ dir = back
+ ]
+
+ msg_handler -> control
+
+ // UML Composition relationships
+ edge [
+ arrowtail = diamond,
+ dir = back
+ ]
+
+ control -> adapt01
+ control -> adapt02
+ control -> adapt03
+ control -> adapt04
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Note that this diagram is not the best example of efficient
+// graphviz/doxygen use. It was recreating the look of an existing
+// graphic and thus is focused too much on appearance over
+// functionality.
+//
+
+digraph G {
+ label = "Abstracted Architecture";
+
+ z [
+ label = "Resource Introspection",
+ shape = box,
+ style = filled,
+ fillcolor="#efefef:#bdbdbd",
+ gradientangle=270,
+ width=8
+ ];
+
+ subgraph cluster_0 {
+ label = "Connectivity Framework";
+ labeljust="l";
+
+ yy [
+ label = "Connectivity API",
+ shape = box,
+ style = filled,
+ color = "#4a7bbd",
+ fillcolor="#e6efff:#a5c5ff",
+ gradientangle=270,
+ width=8
+ ];
+
+ subgraph cluster_1 {
+ label = "Control layer";
+ style=filled;
+ color = "#4a7bbd";
+ fillcolor="#e6efff:#a5c5ff";
+ gradientangle=270;
+
+ node [
+ style=filled,
+ color="#9cbd52",
+ fillcolor="#f7ffe6:#deffad",
+ gradientangle=270,
+ shape=box
+ ];
+
+ a0 [label="Network\nConfiguration"];
+ a1 [label="CoAP\nProtocol"];
+ a2 [label="Interface\nController"];
+
+ {rank = same a0 a1 a2}
+ }
+
+ subgraph cluster_2 {
+ label = "Transport Adapter";
+ style=filled;
+ color = "#4a7bbd"
+ fillcolor="#e6efff:#a5c5ff";
+ gradientangle=270;
+ node [
+ style=filled,
+ color="#9cbd52",
+ fillcolor="#f7ffe6:#deffad",
+ gradientangle=270,
+ shape=box
+ ];
+
+ bb [label = "Common Adapter Interface", width=5];
+
+ b0 [label="IP\nAdapter"];
+ b1 [label="LE GATT\nAdapter"];
+ b2 [label="BT SPP\nAdapter"];
+ b3 [label="XXX\nAdapter"];
+
+ {rank = same b0 b1 b2 b3}
+ }
+
+ subgraph cluster_3 {
+ label = "Platform Adapter";
+ style=filled;
+ color = "#4a7bbd"
+ fillcolor="#e6efff:#a5c5ff";
+ gradientangle=270;
+ node [
+ style=filled
+ color="#7b5aa5"
+ fillcolor="#f7e6f7:#c5b5ef";
+ gradientangle=270;
+ shape=box
+ ];
+
+ c0 [label="Ubuntu\nAdapter\n(ETH/WIFI/BT)"];
+ c1 [label="Android\nAdapter\n(WIFI/BLE/BT)"];
+ c2 [label="Tizen\nAdapter\n(WIFI/BLE/BT)"];
+ c3 [label="Arduino\nAdapter\n(ETH/WIFI/BLE)"];
+ c4 [label="Platform\n(6loWPAN)\n ", color="#f7e6f7"];
+
+ {rank = same c0 c1 c2 c3 c4}
+ }
+ }
+
+ {
+ node [
+ style = filled,
+ fillcolor="#efefef:#bdbdbd",
+ gradientangle=270,
+ shape=box
+ ];
+
+ d0 [label="Ubuntu"];
+ d1 [label="Android"];
+ d2 [label="Tizen"];
+ d3 [label="Arduino"];
+ d4 [label="????"];
+
+ {rank = same d0 d1 d2 d3 d4}
+ }
+
+ subgraph cluster_lgd {
+ label = "Legend";
+
+ node [
+ style = filled,
+ width=0.25,
+ height=0.25,
+ fixedsize=true,
+ shape=box,
+ gradientangle=270
+ ];
+
+ e0 [label=" ", color="#4a7bbd", fillcolor="#e6efff:#a5c5ff"];
+ e1 [label=" ", color="#9cbd52", fillcolor="#f7ffe6:#deffad"];
+ e2 [label=" ", color="#7b5aa5", fillcolor="#f7e6f7:#c5b5ef"];
+ e3 [label=" ", fillcolor="#efefef:#bdbdbd"];
+ e_dummy[shape=point, style=invis];
+
+ edge [penwidth=0,
+ arrowhead=none,
+ fontsize=10];
+ e0 -> e1 [label="CA Component "];
+ e1 -> e2 [label="CA Module-platform independent "];
+ e2 -> e3 [label="CA Module-platform specific "];
+ e3 -> e_dummy [label="External"];
+
+ {rank = same e0 e1 e2 e3 e_dummy}
+ }
+
+ // In order to control placement of the sets of items in a
+ // top-to-bottom placement, invisible edges/arrows are used.
+ // This gives a logcial control for the physical appearance we want.
+ {
+ edge[style = invis];
+
+ // order groups to get top-to-bottom
+ z -> yy
+ yy -> {a0 a2}
+ a1 -> bb
+ {a0 a2} -> {b1 b2}
+ bb -> {b1 b2}
+ {b0 b1 b2 b3} -> c2
+ c0 -> d0
+ c1 -> d1
+ c2 -> d2
+ c3 -> d3
+ d0 -> e0
+ {d2} -> {e1 e2}
+ d4 -> e3
+
+ // order nodes left-to-right
+ a0 -> a1 -> a2
+ b0 -> b1 -> b2 -> b3
+ c0 -> c1 -> c2 -> c3 -> c4
+ d0 -> d1 -> d2 -> d3 -> d4
+ e0 -> e1 -> e2 -> e3
+ }
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+/**
+@mainpage
+
+This is documentation intended for internal use of developers actually
+working on the implementation code itself. At the moment this specific page
+is just a simplified placeholder.
+
+<hr>
+
+Quick starting points:
+
+- @ref ca_overview which replicates an existing requirements doc.
+ - An overview diagram in that document: @ref cao_overview
+- @ref ca_functional Minimal sample showing how diagrams and code doc can be
+ integrated.
+ - @ref caf_ovr_comm_netinterface a section with a minimal UML sketch
+ - @ref caf_ovr_comm_netinterface_detail a more detailed UML diagram
+- The 'Related Pages' tab
+
+Then see CAEthernetInitializeServer() for...
+- CAInitializeEthernet()
+- other
+*/
\ No newline at end of file
--- /dev/null
+<doxygenlayout version="1.0">
+ <navindex>
+ <tab type="mainpage" visible="yes" title="Home"/>
+ <tab type="classes" visible="yes" title="API Reference">
+ <tab type="classlist" visible="yes" title=""/>
+ <tab type="hierarchy" visible="yes" title="" intro=""/>
+ <tab type="classmembers" visible="yes" title="" intro=""/>
+ </tab>
+ <tab type="files" visible="yes" title="">
+ <tab type="filelist" visible="yes" title="" intro=""/>
+ <tab type="globals" visible="yes" title="" intro=""/>
+ </tab>
+ </navindex>
+</doxygenlayout>
--- /dev/null
+/*!
+
+@mainpage Welcome
+
+IoTivity is an open source software framework enabling seamless device-to-device connectivity to address the emerging needs of the Internet of Things. These API references are for any developer trying to utilize the IoTivity project for building applications.
+
+\li <a href="annotated.html"><strong>API References</strong></a><br />Provides a reference to all public APIs available to utilize the power of IoTivity.
+
+\li <a href="https://www.iotivity.org/documentation"><strong>Getting Started Guides and Tutorials</strong></a><br />Detailed getting started guides and tutorials can be found on the iotivity.org website.
+
+\li <a href="https://wiki.iotivity.org"><strong>Wiki</strong></a><br />Additional documentation can be found on the IoTivity Wiki.
+
+*/
--- /dev/null
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
+ <li class="footer">Generated on $datetime</li>
+ </ul>
+</div>
+</body>
+</html>
\ No newline at end of file
EASYSETUP_PATH="../../service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/"
EASYSETUP_PKG=org.iotivity.service.easysetup.mediator
-SIMULATOR_PATH="../../service/simulator/java/sdk/src/"
-SIMULATOR_COMMON_PKG=org.oic.simulator
-SIMULATOR_CLIENT_PKG=org.oic.simulator.clientcontroller
-SIMULATOR_SERVER_PKG=org.oic.simulator.serviceprovider
RESOURCECONTAINER_PATH="../../service/resource-container/android/resource-container/src/main/java/"
RESOURCECONTAINER_PKG=org.iotivity.service.resourcecontainer
javadoc -public -splitindex -d ./Java_API -sourcepath \
- $BASE_PATH:$RE_PATH:$RH_PATH:$EASYSETUP_PATH:$RESOURCECONTAINER_PATH:$SIMULATOR_PATH \
+ $BASE_PATH:$RE_PATH:$RH_PATH:$EASYSETUP_PATH:$RESOURCECONTAINER_PATH \
$BASE_PKG $RE_COMMON_PKG $RE_CLINET_PKG $RE_SERVER_PKG $TM_SRCS $TM_PKG $RH_PKG $EASYSETUP_PKG \
- $SIMULATOR_COMMON_PKG $SIMULATOR_CLIENT_PKG $RESOURCECONTAINER_PKG $SIMULATOR_SERVER_PKG
+ $RESOURCECONTAINER_PKG
threadingsample = examples_env.Program('threadingsample', 'threadingsample.cpp')
clientjson = examples_env.Install(env.get('BUILD_DIR') + '/resource/examples/',
- env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_client.json')
+ env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_client.dat')
serverjson = examples_env.Install(env.get('BUILD_DIR') + '/resource/examples/',
- env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_server.json')
+ env.get('SRC_DIR') + '/resource/examples/' + 'oic_svr_db_server.dat')
Alias("examples", [simpleserver, simpleclient,
simpleserverHQ, simpleclientHQ,
fridgeserver, fridgeclient,
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl"
- ],
- "perms": 2,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MjIyMjIyMjIyMjIyMjIyMg==",
- "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MTExMTExMTExMTExMTExMQ==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "32323232-3232-3232-3232-323232323232"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+ "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "31313131-3131-3131-3131-313131313131",\r
+ "credtype": 1,\r
+ "privatedata": {\r
+ "data": "AAAAAAAAAAAAAAAA",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232"\r
+ }\r
+}
\ No newline at end of file
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": ["/a/light"],
- "perms": 6,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MTExMTExMTExMTExMTExMQ==",
- "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/a/light",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "31313131-3131-3131-3131-313131313131"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+ "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "32323232-3232-3232-3232-323232323232",\r
+ "credtype": 1,\r
+ "privatedata": {\r
+ "data": "AAAAAAAAAAAAAAAA",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131"\r
+ }\r
+}
\ No newline at end of file
using namespace OC;
+static const char* SVR_DB_FILE_NAME = "./oic_svr_db_client.dat";
typedef std::map<OCResourceIdentifier, std::shared_ptr<OCResource>> DiscoveredResourceMap;
DiscoveredResourceMap discoveredResources;
static FILE* client_open(const char* /*path*/, const char *mode)
{
- return fopen("./oic_svr_db_client.json", mode);
+ return fopen(SVR_DB_FILE_NAME, mode);
}
int main(int argc, char* argv[]) {
using namespace std;
namespace PH = std::placeholders;
+static const char* SVR_DB_FILE_NAME = "./oic_svr_db_server.dat";
int gObservation = 0;
void * ChangeLightRepresentation (void *param);
void * handleSlowResponse (void *param, std::shared_ptr<OCResourceRequest> pRequest);
static FILE* client_open(const char* /*path*/, const char *mode)
{
- return fopen("./oic_svr_db_server.json", mode);
+ return fopen(SVR_DB_FILE_NAME, mode);
}
int main(int argc, char* argv[])
* all the device in subnet which are not yet owned.
*
* @param timeout Timeout in seconds, time until which function will listen to
- * responses from client before returning the list of devices.
+ * responses from server before returning the list of devices.
* @param list List of candidate devices to be provisioned.
* @return ::OC_STACK_OK in case of success and other value otherwise.
*/
* all the device in subnet which are already owned by calling provisioning client.
*
* @param timeout Timeout in seconds, time until which function will listen to
- * responses from client before returning the list of devices.
+ * responses from server before returning the list of devices.
* @param list List of owned devices.
* @return ::OC_STACK_OK in case of success and other value otherwise.
*/
'../csdk/security/include',
'../csdk/security/provisioning/include',
'../csdk/security/provisioning/include/oxm',
- '../csdk/security/provisioning/include/internal'
+ '../csdk/security/provisioning/include/internal',
+ '../csdk/connectivity/lib/libcoap-4.1.1/',
+ '../../extlibs/cjson/'
])
target_os = env.get('TARGET_OS')
--- /dev/null
+LAST UPDATED 3/28/2016
+
+To execute Provisioning Tool sample:
+
+1) Build IoTivity with security enabled:
+
+ $ cd <iotivity-base>
+ $ scons resource SECURED=1
+
+2) Verify Provisioning Tool functionality using secure sample apps:
+
+ Run Resource Server Device which needs to be 'provisioned' in the directory
+ <iotivity-base>/out/<...>/resource/csdk/security/provisioning/samples:
+ $ <...>/sampleserver_justworks (Just Works)
+ or
+ $ <...>/sampleserver_randompin (Random Pin)
+
+ Run Provisioning Tool Device:
+ $ ./provisioningclient
+
+ Provisioning Tool will provide prompts for discovery, ownership transfer, and provisioning.
+
+ Enter 1 (UnOwned Device discovery)
+ and you should see the list of discovered unowned devices.
+
+ Then enter 3 (Ownership transfer) and the number of device
+ you want to perform ownership transfer between the Server device and
+ the Provisioning Tool device.
+
+ If the random pin server is running, you must enter the PIN code that
+ appears on the server terminal to finish ownership transfer.
+
+ Enter 2 (Owned Device discovery) to confirm that
+ ownership transfer succeeded. If successful,
+ you should find the Server device on the Owned device list.
+
+ 3) Verify Ownership Transfer using sample apps:
+
+ If you would like to check whether ownership transfer successfully
+ created credentials, replace the server and client sample DAT files
+ with oic_svr_db_client.dat and oic_svr_db_server.dat files from the
+ ownership transfer as follows:
+ $ cp ./oic_svr_db_client.dat <iotivity-base>/out/<...>/release/resource/csdk/stack/samples/linux/secure/oic_svr_db.client.dat
+ $ cp <iotivity-base>/out/release/resource/csdk/security/provisioning/samples/oic_svr_db_server_<...>.dat <iotivity-base>/out/<...>/release/resource/csdk/stack/samples/linux/secure/oic_svr_db.server.dat
+
+ Then move to the sample app directory
+ and execute the server and client apps:
+ $ cd <iotivity-base>/out/release/resource/csdk/stack/samples/linux/secure/
+ $ export LD_LIBRARY_PATH=<iotivity-base>/out/<...>/release/
+ $ ./ocserverbasicops
+ $ ./occlientbasicops -u 0 -t 3
+
+ If successful, the client and server should successfully send and receive payloads.
+
+ All security functionality operate using CBOR data (DAT files).
+ JSON files are for reference only as they are human-readable.
+ JSON files are not used by security-related functions.
+
+ If you wish to test functionality with data file
+ different from the provided default DAT file, modify the JSON files
+ (oic_svr_db_server_justworks.json, oic_svr_db_server_randompin.json)
+ and then use the JSON-to-CBOR conversion tool
+ (<iotivity-base>/out/<...>/release/resource/csdk/security/tool/json2cbor)
+ to create a new DAT file.
svr_db_build_dir = env.get('BUILD_DIR') +'/resource/provisioning/examples/'
clientjson = examples_env.Install(svr_db_build_dir, svr_db_src_dir + 'oic_svr_db_client.json')
+clientdat = examples_env.Install(svr_db_build_dir, svr_db_src_dir + 'oic_svr_db_client.dat')
-Alias("examples", [provisioningclient, clientjson])
+Alias("examples", [provisioningclient, clientjson,clientdat])
env.AppendTarget('examples')
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/amacl"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlEMA=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["YWRtaW5EZXZpY2VVVUlEMA=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlEMA==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "YWRtaW5EZXZpY2VVVUlEMA==",
- "ownr": "YWRtaW5EZXZpY2VVVUlEMA=="
- }
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/amacl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } \r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "61646D69-6E44-6576-6963-655575696430"\r
+ }, \r
+ "pstat": {\r
+ "isop": true,\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3,\r
+ "deviceuuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "rowneruuid": "61646D69-6E44-6576-6963-655575696430"\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "dpc": false,\r
+ "devowneruuid": "61646D69-6E44-6576-6963-655575696430",\r
+ "rowneruuid": "61646D69-6E44-6576-6963-655575696430"\r
+ }\r
+}\r
#define TAG "provisioningclient"
#define JSON_DB_PATH "./oic_svr_db_client.json"
+#define DAT_DB_PATH "./oic_svr_db_client.dat"
#define DEV_STATUS_ON "DEV_STATUS_ON"
#define DEV_STATUS_OFF "DEV_STATUS_OFF"
static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
{
(void)UNUSED_PARAM;
- return fopen(JSON_DB_PATH, mode);
+ return fopen(DAT_DB_PATH, mode);
}
void printMenu()
}
OICFree((acl)->resources);
- /* Clean Owners */
- OICFree((acl)->owners);
-
/* Clean ACL node itself */
/* Required only if acl was created in heap */
OICFree((acl));
} while (0 != ret );
// Set Rowner
- printf("Num. of Rowner : ");
- ret = scanf("%zu", &acl->ownersLen);
- if ((1 != ret) || (acl->ownersLen <= 0 || acl->ownersLen > 20))
- {
- printf("Error while input\n");
- return -1;
- }
printf("-URN identifying the rowner\n");
printf("ex) 1111-1111-1111-1111 (16 Numbers except to '-')\n");
- acl->owners = (OicUuid_t *)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
- if (NULL == acl->owners)
+
+ printf("Rowner : ");
+ ret = scanf("%19ms", &temp_id);
+ if (1 != ret)
{
- OIC_LOG(ERROR, TAG, "Error while memory allocation");
+ printf("Error while input\n");
return -1;
}
- for (size_t i = 0; i < acl->ownersLen; i++)
- {
- printf("[%zu]Rowner : ", i + 1);
- ret = scanf("%19ms", &temp_id);
- if (1 != ret)
- {
- printf("Error while input\n");
- return -1;
- }
- for (int k = 0, j = 0; temp_id[k] != '\0'; k++)
+ for (int k = 0, j = 0; temp_id[k] != '\0'; k++)
+ {
+ if (DASH != temp_id[k])
{
- if (DASH != temp_id[k])
- {
- acl->owners[i].id[j++] = temp_id[k];
- }
+ acl->rownerID.id[j++] = temp_id[k];
}
- OICFree(temp_id);
}
+ OICFree(temp_id);
+
return 0;
}
OTMCallbackData_t pinBasedCBData;
pinBasedCBData.loadSecretCB = InputPinCodeCallback;
pinBasedCBData.createSecureSessionCB =
- CreateSecureSessionRandomPinCallbak;
+ CreateSecureSessionRandomPinCallback;
pinBasedCBData.createSelectOxmPayloadCB =
CreatePinBasedSelectOxmPayload;
pinBasedCBData.createOwnerTransferPayloadCB =
* *****************************************************************/
#include "ocstack.h"
+#include "srmutility.h"
#include "base64.h"
#include "OCProvisioningManager.h"
if(!resultCallback)
{
oclog() <<"Result callback can't be null";
- return OC_STACK_INVALID_PARAM;
+ return OC_STACK_INVALID_CALLBACK;
}
OCStackResult result;
OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
ResultCallBack resultCallback)
{
- if(!resultCallback || !acl)
+ if(!acl)
{
- oclog() <<"Result callback or ACL can't be null";
+ oclog() <<"ACL can't be null";
return OC_STACK_INVALID_PARAM;
}
+ if(!resultCallback)
+ {
+ oclog() <<"result callback can not be null";
+ return OC_STACK_INVALID_CALLBACK;
+ }
OCStackResult result;
auto cLock = m_csdkLock.lock();
if(!resultCallback)
{
oclog() << "Result calback can't be null";
- return OC_STACK_INVALID_PARAM;
+ return OC_STACK_INVALID_CALLBACK;
}
OCStackResult result;
{
if(!resultCallback)
{
- oclog() << "Result calback can't be null";
- return OC_STACK_INVALID_PARAM;
+ oclog() << "Result callback can not be null";
+ return OC_STACK_INVALID_CALLBACK;
}
OCStackResult result;
if(!resultCallback)
{
oclog() << "Result calback can't be null";
- return OC_STACK_INVALID_PARAM;
+ return OC_STACK_INVALID_CALLBACK;
}
OCStackResult result;
if(!resultCallback)
{
oclog() << "Result calback can't be null";
- return OC_STACK_INVALID_PARAM;
+ return OC_STACK_INVALID_CALLBACK;
}
OCStackResult result;
std::string OCSecureResource::getDeviceID()
{
- char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {0,};
- uint32_t outLen = 0;
- B64Result b64Ret = B64_OK;
std::ostringstream deviceId("");
+ char *devID = nullptr;
validateSecureResource();
- b64Ret = b64Encode(devPtr->doxm->deviceID.id, sizeof(devPtr->doxm->deviceID.id), base64Buff,
- sizeof(base64Buff), &outLen);
- if (B64_OK == b64Ret)
+ if (OC_STACK_OK == ConvertUuidToStr(&(devPtr->doxm->deviceID), &devID))
+ {
+ deviceId << devID;
+ }
+ else
{
- deviceId << base64Buff;
+ oclog() <<"Can not convert uuid to struuid";
}
return deviceId.str();
}
TEST(DiscoveryTest, UnownedDevicesZeroTimeout)
{
DeviceList_t list;
- EXPECT_EQ(OC_STACK_OK, OCSecure::discoverUnownedDevices(0, list));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::discoverUnownedDevices(0, list));
}
TEST(DiscoveryTest, OwnedDevices)
TEST(DiscoveryTest, OwnedDevicesZeroTimeout)
{
DeviceList_t list;
- EXPECT_EQ(OC_STACK_OK, OCSecure::discoverOwnedDevices(0, list));
+ EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::discoverOwnedDevices(0, list));
}
TEST(OwnershipTest, SetOwnershipTransferCBDataNull)
{
OTMCallbackData_t pinBasedCBData;
pinBasedCBData.loadSecretCB = InputPinCodeCallback;
- pinBasedCBData.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
+ pinBasedCBData.createSecureSessionCB = CreateSecureSessionRandomPinCallback;
pinBasedCBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
pinBasedCBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
OTMSetOwnershipTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &pinBasedCBData);
TEST(OwnershipTest, OwnershipTransferNullCallback)
{
OCSecureResource device;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, device.doOwnershipTransfer(nullptr));
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.doOwnershipTransfer(nullptr));
}
TEST(DeviceInfoTest, DevInfoFromNetwork)
{
OCSecureResource device;
OicSecAcl_t *acl = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
- EXPECT_EQ(OC_STACK_INVALID_PARAM, device.provisionACL(acl, nullptr));
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.provisionACL(acl, nullptr));
OICFree(acl);
}
{
OCSecureResource device, dev2;
Credential cred;
- EXPECT_EQ(OC_STACK_INVALID_PARAM, device.provisionCredentials(cred, dev2, nullptr));
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.provisionCredentials(cred, dev2, nullptr));
}
TEST(ProvisionPairwiseTest, ProvisionPairwiseTestNullCallback)
Credential cred;
OicSecAcl_t *acl1 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
OicSecAcl_t *acl2 = (OicSecAcl_t *)OICCalloc(1,sizeof(OicSecAcl_t));
- EXPECT_EQ(OC_STACK_INVALID_PARAM, device.provisionPairwiseDevices(cred, acl1,
+ EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.provisionPairwiseDevices(cred, acl1,
dev2, acl2, nullptr));
OICFree(acl1);
OICFree(acl2);
return OC_STACK_KEEP_TRANSACTION;
}
- ListenOCContainer container(clientWrapper, clientResponse->devAddr,
- reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
- // loop to ensure valid construction of all resources
- for(auto resource : container.Resources())
- {
- std::thread exec(context->callback, resource);
- exec.detach();
+ try{
+ ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+ reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
+ // loop to ensure valid construction of all resources
+ for(auto resource : container.Resources())
+ {
+ std::thread exec(context->callback, resource);
+ exec.detach();
+ }
+ }
+ catch (std::exception &e){
+ oclog() << "Exception in listCallback, ignoring response: "
+ << e.what() << std::flush;
}
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <OCApi.h>
+#include "OCApi.h"
-#include <OCUtilities.h>
+#include "OCUtilities.h"
#include <boost/algorithm/string.hpp>
{
using namespace OC;
+ static const char* SVR_DB_FILE_NAME = "./oic_svr_db_server.dat";
const OCResourceHandle HANDLE_ZERO = 0;
const std::string gResourceTypeName = "core.res";
const std::string gResourceInterface = DEFAULT_INTERFACE;
//OCPersistent Storage Handlers
static FILE* client_open(const char * /*path*/, const char *mode)
{
- std::cout << "<===Opening SVR DB file = './oic_svr_db_client.json' with mode = '" << mode
+ std::cout << "<===Opening SVR DB file = './oic_svr_db_client.dat' with mode = '" << mode
<< "' " << std::endl;
- return fopen("./oic_svr_db_client.json", mode);
+ return fopen(SVR_DB_FILE_NAME, mode);
}
OCPersistentStorage gps {client_open, fread, fwrite, fclose, unlink };
OCDeviceInfo deviceInfo;
DuplicateString(&deviceInfo.deviceName, "myDeviceName");
deviceInfo.types = NULL;
+ OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.wk.d");
OCResourcePayloadAddStringLL(&deviceInfo.types, "oic.d.tv");
EXPECT_EQ(OC_STACK_OK, OCPlatform::registerDeviceInfo(deviceInfo));
EXPECT_NO_THROW(DeleteDeviceInfo(deviceInfo));
unittests_env.Alias("install",
unittests_env.Install(svr_db_build_dir,
os.path.join(svr_db_src_dir,
- 'oic_svr_db_client.json')))
+ 'oic_svr_db_client.dat')))
* @var gEnrolleeStatusCb
* @brief Fucntion pointer holding the callback for intimation of EasySetup Enrollee status callback
*/
-static EventCallback gEnrolleeStatusCb = NULL;
+static ESEnrolleeEventCallback gEnrolleeStatusCb = NULL;
/**
* @var gIsSecured
//-----------------------------------------------------------------------------
// Private internal function prototypes
//-----------------------------------------------------------------------------
-void OnboardingCallback(ESResult esResult);
-void ProvisioningCallback(ESResult esResult);
-void OnboardingCallbackTargetNet(ESResult esResult);
-static bool ValidateParam(OCConnectivityType networkType, const char *ssid, const char *passwd,
- EventCallback cb);
+void ESOnboardingCallback(ESResult esResult);
+void ESProvisioningCallback(ESResult esResult);
+void ESOnboardingCallbackTargetNet(ESResult esResult);
+static bool ESEnrolleeValidateParam(OCConnectivityType networkType, const char *ssid,
+ const char *passwd, ESEnrolleeEventCallback cb);
-void OnboardingCallback(ESResult esResult)
+void ESOnboardingCallback(ESResult esResult)
{
- OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "OnboardingCallback with result = %d", esResult);
+ OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESOnboardingCallback with result = %d", esResult);
if(esResult == ES_OK)
{
gEnrolleeStatusCb(esResult, ES_ON_BOARDED_STATE);
}
}
-void ProvisioningCallback(ESResult esResult)
+void ESProvisioningCallback(ESResult esResult)
{
- OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ProvisioningCallback with result = %d", esResult);
+ OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESProvisioningCallback with result = %d", esResult);
if (esResult == ES_RECVTRIGGEROFPROVRES)
{
OIC_LOG(DEBUG, ES_ENROLLEE_TAG, "Connecting with target network");
// Connecting/onboarding to target network
- ConnectToWiFiNetwork(gTargetSsid, gTargetPass, OnboardingCallbackTargetNet);
+ ConnectToWiFiNetwork(gTargetSsid, gTargetPass, ESOnboardingCallbackTargetNet);
}
else
{
}
}
-void OnboardingCallbackTargetNet(ESResult esResult)
+void ESOnboardingCallbackTargetNet(ESResult esResult)
{
- OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "OnboardingCallback on target network with result = %d",
+ OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESOnboardingCallback on target network with result = %d",
esResult);
if(esResult == ES_OK)
{
}
}
-ESResult InitEasySetup(OCConnectivityType networkType, const char *ssid, const char *passwd,
+ESResult ESInitEnrollee(OCConnectivityType networkType, const char *ssid, const char *passwd,
bool isSecured,
- EventCallback cb)
+ ESEnrolleeEventCallback cb)
{
- OIC_LOG(INFO, ES_ENROLLEE_TAG, "InitEasySetup IN");
- if(!ValidateParam(networkType,ssid,passwd,cb))
+ OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitEnrollee IN");
+ if(!ESEnrolleeValidateParam(networkType,ssid,passwd,cb))
{
OIC_LOG(ERROR, ES_ENROLLEE_TAG,
- "InitEasySetup::Stopping Easy setup due to invalid parameters");
+ "ESInitEnrollee::Stopping Easy setup due to invalid parameters");
return ES_ERROR;
}
OIC_LOG(INFO, ES_ENROLLEE_TAG, "received callback");
OIC_LOG(INFO, ES_ENROLLEE_TAG, "onboarding now..");
- if(!ESOnboard(ssid, passwd, OnboardingCallback))
+ if(!ESOnboard(ssid, passwd, ESOnboardingCallback))
{
- OIC_LOG(ERROR, ES_ENROLLEE_TAG, "InitEasySetup::On-boarding failed");
+ OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESInitEnrollee::On-boarding failed");
cb(ES_ERROR, ES_INIT_STATE);
return ES_ERROR;
}
- OIC_LOG(INFO, ES_ENROLLEE_TAG, "InitEasySetup OUT");
+ OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitEnrollee OUT");
return ES_OK;
}
-ESResult TerminateEasySetup()
+ESResult ESTerminateEnrollee()
{
UnRegisterResourceEventCallBack();
return ES_ERROR;
}
- OIC_LOG(ERROR, ES_ENROLLEE_TAG, "TerminateEasySetup success");
+ OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESTerminateEnrollee success");
return ES_OK;
}
-ESResult InitProvisioning()
+ESResult ESInitProvisioning()
{
- OIC_LOG(INFO, ES_ENROLLEE_TAG, "InitProvisioning <<IN>>");
+ OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitProvisioning <<IN>>");
if (CreateProvisioningResource(gIsSecured) != OC_STACK_OK)
{
return ES_ERROR;
}
- RegisterResourceEventCallBack(ProvisioningCallback);
+ RegisterResourceEventCallBack(ESProvisioningCallback);
- OIC_LOG(INFO, ES_ENROLLEE_TAG, "InitProvisioning OUT");
+ OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitProvisioning <<OUT>>");
return ES_RESOURCECREATED;
}
-static bool ValidateParam(OCConnectivityType /*networkType*/, const char *ssid, const char *passwd,
- EventCallback cb)
+static bool ESEnrolleeValidateParam(OCConnectivityType /*networkType*/, const char *ssid,
+ const char *passwd, ESEnrolleeEventCallback cb)
{
if (!ssid || !passwd || !cb)
{
- OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ValidateParam - Invalid parameters");
+ OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESEnrolleeValidateParam - Invalid parameters");
return false;
}
return true;
/**
* It will do onboarding based on the user's configuration.
*/
-bool ESOnboard(const char * ssid, const char* passwd, NetworkEventCallback cb)
+bool ESOnboard(const char * ssid, const char* passwd, ESEnrolleeNetworkEventCallback cb)
{
OIC_LOG(DEBUG, ES_ENROLLEE_TAG, "ESOnboard IN");
if (ESSoftapOnboarding())
{
- //Arduino does not need to check ESSoftapAtEnrollee()
- //As SoftAP for Arduino Enrollee will be created at Mediator side &
- //Arduino Enrollee always connects to the mediator's softAp.
-
OIC_LOG(DEBUG, ES_ENROLLEE_TAG, "Connecting to Mediator SoftAp");
ConnectToWiFiNetwork(ssid, passwd, cb);
return true;
OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest);
-ResourceEventCallback gNetworkInfoProvEventCb = NULL;
+ESEnrolleeResourceEventCallback gNetworkInfoProvEventCb = NULL;
-void RegisterResourceEventCallBack(ResourceEventCallback cb)
+void RegisterResourceEventCallBack(ESEnrolleeResourceEventCallback cb)
{
gNetworkInfoProvEventCb = cb;
}
void ESCreateSoftapCallback(int result, const char *ip, const char* mac_addr,
const char* device_name );
-NetworkEventCallback gCallback;
+ESEnrolleeNetworkEventCallback gCallback;
/**
* It will return Device which is creating Soft AP.
/**
* This API will create the softap at enrollee
*/
-void ESCreateSoftap(const char * ssid, const char* passwd, NetworkEventCallback cb)
+void ESCreateSoftap(const char * ssid, const char* passwd, ESEnrolleeNetworkEventCallback cb)
{
gCallback = cb;
/**
* @var g_retryCounter
- * @brief Retry counter for cancelling network retry. Currently network retry is limited to 5 attempts
+ * @brief Retry counter for cancelling network retry. Currently network retry is
+ * limited to 5 attempts
*/
static uint16_t g_retryCounter = 0;
// this server will NOT be listening on 224.0.1.187 multicast address.
static const char ARDUINO_WIFI_SHIELD_UDP_FW_VER[] = "1.1.0";
-ESResult ConnectToWiFiNetwork(const char *ssid, const char *pass, NetworkEventCallback cb)
+ESResult ConnectToWiFiNetwork(const char *ssid, const char *pass,
+ ESEnrolleeNetworkEventCallback cb)
{
char *fwVersion;
int status = WL_IDLE_STATUS;
*
* @param esResult ESResult provides the current state of the network connection status
*/
-typedef void (*NetworkEventCallback)(ESResult esResult);
+typedef void (*ESEnrolleeNetworkEventCallback)(ESResult esResult);
typedef struct
{
byte mac[6];
} NetworkInfo;
-ESResult ConnectToWiFiNetwork(const char *ssid, const char *pass, NetworkEventCallback);
+ESResult ConnectToWiFiNetwork(const char *ssid, const char *pass,
+ ESEnrolleeNetworkEventCallback);
ESResult getCurrentNetworkInfo(OCConnectivityType targetType, NetworkInfo *info);
#endif
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-/**
- * @file
- *
- * This file contains SDK APIs for device operating in Enrollee Mode of EasySetup
- */
#ifndef EASYSETUP_ENROLLEE_H__
#define EASYSETUP_ENROLLEE_H__
#include "escommon.h"
+/**
+ * @file
+ *
+ * This file contains Enrollee APIs
+ */
+
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/*
- * Callback function for updating the Enrollee OnBoarding and Provisioning status result to the application
+ * Callback function for updating the Enrollee OnBoarding and Provisioning status result
+ * to the application
*
* @param esResult ESResult provides the current state of the Enrollee Device
*/
-typedef void (*EventCallback)(ESResult esResult, EnrolleeState enrolleeState);
+typedef void (*ESEnrolleeEventCallback)(ESResult esResult, ESEnrolleeState enrolleeState);
/**
* This function Initializes the EasySetup. This API must be called prior to invoking any other API
*
* @param networkType NetworkType on which OnBoarding has to be performed.
* @param ssid SSID of the target SoftAP network to which the Enrollee is connecting.
- * @param passwd Password of the target SoftAP network to which the Enrollee is connecting
+ * @param passwd Password of the target SoftAP network to which the Enrollee is
+ * connecting
* @param isSecured True if the Enrollee is operating in secured mode.
- * @param eventCallback EventCallback for for updating the Enrollee OnBoarding status result to
- * the application
+ * @param eventCallback ESEnrolleeEventCallback for for updating the Enrollee OnBoarding status
+ * result to the application
* @return ::ES_OK on success, some other value upon failure.
*/
-ESResult InitEasySetup(OCConnectivityType networkType, const char *ssid, const char *passwd,
- bool isSecured,
- EventCallback eventCallback);
+ESResult ESInitEnrollee(OCConnectivityType networkType, const char *ssid, const char *passwd,
+ bool isSecured, ESEnrolleeEventCallback eventCallback);
/**
* This function performs initialization of Provisioning and Network resources needed for EasySetup
* process.
* @return ::ES_OK on success, some other value upon failure.
*/
-ESResult InitProvisioning();
+ESResult ESInitProvisioning();
/**
* This function performs termination of Provisioning and Network resources.
*
* @return ::ES_OK on success, some other value upon failure.
*/
-ESResult TerminateEasySetup();
+ESResult ESTerminateEnrollee();
#ifdef __cplusplus
}
const char *gSsid = "DLNA_LISMORE1";
const char *gPass = "dlna@010203";
char *gIpAddress;
-NetworkEventCallback gNetworkEventCb;
+ESEnrolleeNetworkEventCallback gNetworkEventCb;
/*
* All the functions defined in this file are stub functions to be implemented by the end user of
ESActivateWifi();
}
-void ConnectToWiFiNetwork(const char *ssid, const char *pass, NetworkEventCallback cb)
+void ConnectToWiFiNetwork(const char *ssid, const char *pass,
+ ESEnrolleeNetworkEventCallback cb)
{
OIC_LOG_V(INFO, LOG_TAG, "ConnectToWiFiNetwork %s %s",ssid,pass);
gPass = pass;
*
* @param esResult ESResult provides the current state of the network connection status
*/
-typedef void (*NetworkEventCallback)(ESResult esResult);
+typedef void (*ESEnrolleeNetworkEventCallback)(ESResult esResult);
typedef struct
{
//byte mac[6];
} NetworkInfo;
-void ConnectToWiFiNetwork(const char *ssid, const char *pass, NetworkEventCallback);
+void ConnectToWiFiNetwork(const char *ssid, const char *pass,
+ ESEnrolleeNetworkEventCallback);
ESResult getCurrentNetworkInfo(OCConnectivityType targetType, NetworkInfo *info);
#endif
* @var gEnrolleeStatusCb
* @brief Fucntion pointer holding the callback for intimation of EasySetup Enrollee status callback
*/
-static EventCallback gEnrolleeStatusCb = NULL;
+static ESEnrolleeEventCallback gEnrolleeStatusCb = NULL;
/**
* @var gIsSecured
*/
static bool gIsSecured = false;
-void OnboardingCallback(ESResult esResult)
+void ESOnboardingCallback(ESResult esResult)
{
- OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "OnboardingCallback with result = %d", esResult);
+ OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESOnboardingCallback with result = %d", esResult);
if(esResult == ES_OK)
{
gEnrolleeStatusCb(esResult, ES_ON_BOARDED_STATE);
}
}
-void ProvisioningCallback(ESResult esResult)
+void ESProvisioningCallback(ESResult esResult)
{
- OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ProvisioningCallback with result = %d", esResult);
+ OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESProvisioningCallback with result = %d", esResult);
if (esResult == ES_RECVTRIGGEROFPROVRES)
{
OIC_LOG(DEBUG, ES_ENROLLEE_TAG, "Connecting with target network");
// Connecting/onboarding to target network
- ConnectToWiFiNetwork(gTargetSsid, gTargetPass, OnboardingCallbackTargetNet);
+ ConnectToWiFiNetwork(gTargetSsid, gTargetPass, ESOnboardingCallbackTargetNet);
}
else
{
}
}
-void OnboardingCallbackTargetNet(ESResult esResult)
+void ESOnboardingCallbackTargetNet(ESResult esResult)
{
- OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "OnboardingCallback on target network with result = %d",
+ OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESOnboardingCallback on target network with result = %d",
esResult);
if(esResult == ES_OK)
{
}
}
-ESResult InitEasySetup(OCConnectivityType networkType, const char *ssid, const char *passwd,
+ESResult ESInitEnrollee(OCConnectivityType networkType, const char *ssid, const char *passwd,
bool isSecured,
- EventCallback cb)
+ ESEnrolleeEventCallback cb)
{
- OIC_LOG(INFO, ES_ENROLLEE_TAG, "InitEasySetup IN");
- if(!ValidateParam(networkType,ssid,passwd,cb))
+ OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitEnrollee IN");
+ if(!ESEnrolleeValidateParam(networkType,ssid,passwd,cb))
{
OIC_LOG(ERROR, ES_ENROLLEE_TAG,
- "InitEasySetup::Stopping Easy setup due to invalid parameters");
+ "ESInitEnrollee::Stopping Easy setup due to invalid parameters");
return ES_ERROR;
}
OIC_LOG(INFO, ES_ENROLLEE_TAG, "received callback");
OIC_LOG(INFO, ES_ENROLLEE_TAG, "onboarding now..");
- if(!ESOnboard(ssid, passwd, OnboardingCallback))
+ if(!ESOnboard(ssid, passwd, ESOnboardingCallback))
{
- OIC_LOG(ERROR, ES_ENROLLEE_TAG, "InitEasySetup::On-boarding failed");
+ OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESInitEnrollee::On-boarding failed");
cb(ES_ERROR, ES_INIT_STATE);
return ES_ERROR;
}
- OIC_LOG(INFO, ES_ENROLLEE_TAG, "InitEasySetup OUT");
+ OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitEnrollee OUT");
return ES_OK;
}
-ESResult TerminateEasySetup()
+ESResult ESTerminateEnrollee()
{
UnRegisterResourceEventCallBack();
return ES_ERROR;
}
- OIC_LOG(ERROR, ES_ENROLLEE_TAG, "TerminateEasySetup success");
+ OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESTerminateEnrollee success");
return ES_OK;
}
-ESResult InitProvisioning()
+ESResult ESInitProvisioning()
{
- OIC_LOG(INFO, ES_ENROLLEE_TAG, "InitProvisioning <<IN>>");
+ OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitProvisioning <<IN>>");
if (CreateProvisioningResource(gIsSecured) != OC_STACK_OK)
{
return ES_ERROR;
}
- RegisterResourceEventCallBack(ProvisioningCallback);
+ RegisterResourceEventCallBack(ESProvisioningCallback);
- OIC_LOG(INFO, ES_ENROLLEE_TAG, "InitProvisioning OUT");
+ OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitProvisioning <<OUT>>");
return ES_RESOURCECREATED;
}
-static bool ValidateParam(OCConnectivityType networkType, const char *ssid, const char *passwd,
- EventCallback cb)
+static bool ESEnrolleeValidateParam(OCConnectivityType networkType, const char *ssid,
+ const char *passwd, ESEnrolleeEventCallback cb)
{
if (!ssid || !passwd || !cb)
{
- OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ValidateParam - Invalid parameters");
+ OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESEnrolleeValidateParam - Invalid parameters");
return false;
}
return true;
/**
* @file
*
- * This file contains private internal callback function
+ * This file contains private internal callback function
* prototypes for Easy setup [Enrollee]
*/
// Private internal callback function prototypes for Easy setup [Enrollee]
//-----------------------------------------------------------------------------
- /*
+ /*
* Callback for on boarding
*/
-void OnboardingCallback(ESResult esResult);
+void ESOnboardingCallback(ESResult esResult);
- /*
+ /*
* Callback for provisioning
*/
-void ProvisioningCallback(ESResult SSSS);
+void ESProvisioningCallback(ESResult SSSS);
- /*
+ /*
* Callback for on boarding target Network
*/
-void OnboardingCallbackTargetNet(ESResult esResult);
+void ESOnboardingCallbackTargetNet(ESResult esResult);
- /*
- * Function for validating the parameter for InitEasySetup API
+ /*
+ * Function for validating the parameter for ESInitEnrollee API
*/
-static bool ValidateParam(OCConnectivityType networkType, const char *ssid, const char *passwd,
- EventCallback cb);
+static bool ESEnrolleeValidateParam(OCConnectivityType networkType, const char *ssid,
+ const char *passwd, ESEnrolleeEventCallback cb);
#ifdef __cplusplus
}
/**
* It will do onboarding based on the user's configuration.
*/
-bool ESOnboard(const char * ssid, const char* passwd, NetworkEventCallback cb)
+bool ESOnboard(const char * ssid, const char* passwd, ESEnrolleeNetworkEventCallback cb)
{
OIC_LOG(DEBUG, ES_ENROLLEE_TAG, "ESOnboard IN");
* @file
*
* This file contains APIs to on-board ( connect ) Enrollee device into Ad-hoc network
- * @Note : Some of the APIs of this file need to be modified by the OEM according to the device configuration
+ * @Note : Some of the APIs of this file need to be modified by the OEM according to the
+ * device configuration
*/
/**
* This function on-board Enrollee device onto ad-hoc network.
- * @param ssid SSID of the target SoftAP network to which the Enrollee is connecting.
- * @param passwd Password of the target SoftAP network to which the Enrollee is connecting.
- * @param NetworkEventCallback Callback function for result update
+ * @param ssid SSID of the target SoftAP network to which the Enrollee
+ * is connecting.
+ * @param passwd Password of the target SoftAP network to which the
+ * Enrollee is connecting.
+ * @param ESEnrolleeNetworkEventCallback Callback function for result update
* @return ::True, if on-boarding is successful.
*/
-bool ESOnboard(const char * ssid, const char* passwd, NetworkEventCallback cb);
+bool ESOnboard(const char * ssid, const char* passwd, ESEnrolleeNetworkEventCallback cb);
/**
* This function verify if the on-boarding is through SoftAP.
OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest);
-ResourceEventCallback gNetworkInfoProvEventCb = NULL;
+ESEnrolleeResourceEventCallback gNetworkInfoProvEventCb = NULL;
-void RegisterResourceEventCallBack(ResourceEventCallback cb)
+void RegisterResourceEventCallBack(ESEnrolleeResourceEventCallback cb)
{
gNetworkInfoProvEventCb = cb;
}
extern "C" {
#endif
-typedef void (*ResourceEventCallback)(ESResult);
+typedef void (*ESEnrolleeResourceEventCallback)(ESResult);
/* Structure to represent a Light resource */
typedef struct PROVRESOURCE
OCStackResult DeleteProvisioningResource();
void GetTargetNetworkInfoFromProvResource(char *, char *);
-void RegisterResourceEventCallBack(ResourceEventCallback);
+void RegisterResourceEventCallBack(ESEnrolleeResourceEventCallback);
void UnRegisterResourceEventCallBack(void);
#ifdef __cplusplus
void ESCreateSoftapCallback(int result, const char *ip, const char* mac_addr,
const char* device_name );
-NetworkEventCallback gCallback;
+ESEnrolleeNetworkEventCallback gCallback;
/**
* It will return Device which is creating Soft AP.
* i.e.Enrollee or Mediator.
- * This decesion is based on, what is the value set for ES_SOFTAP_MODE in build command as well as
+ * This decision is based on, what is the value set for ES_SOFTAP_MODE in build command as well as
* in iotivity.spec file.
*/
DeviceRole ESSoftapHost()
/**
* This API will create the softap at enrollee
*/
-void ESCreateSoftap(const char * ssid, const char* passwd, NetworkEventCallback cb)
+void ESCreateSoftap(const char * ssid, const char* passwd, ESEnrolleeNetworkEventCallback cb)
{
gCallback = cb;
* @file
*
* This file contains platform agnostic API for creation of Soft AP
- * @Note : Some of the APIs of this file need to be modified by the OEM according to the device configuration
+ * @Note : Some of the APIs of this file need to be modified by the OEM according to the device
+ * configuration
*/
/**
/**
* This function Initializes the EasySetup. This API must be called prior to invoking any other API
*
- * @param ssid SSID of the target SoftAP network to which the Enrollee is connecting.
- * @param passwd Password of the target SoftAP network to which the Enrollee is connecting
- * @param NetworkEventCallback Callback function for result update
+ * @param ssid SSID of the target SoftAP network to which the Enrollee is
+ * connecting.
+ * @param passwd Password of the target SoftAP network to which the Enrollee is
+ * connecting
+ * @param ESEnrolleeNetworkEventCallback Callback function for result update
* @return ::void.
*/
-void ESCreateSoftap(const char * ssid, const char* passwd, NetworkEventCallback cb);
+void ESCreateSoftap(const char * ssid, const char* passwd, ESEnrolleeNetworkEventCallback cb);
#ifdef __cplusplus
const char *gPass = "dlna@010203";
char *gIpAddress = NULL;
wifi_ap_h connectedWifi;
-NetworkEventCallback gNetworkEventCb;
+ESEnrolleeNetworkEventCallback gNetworkEventCb;
static void ESActivateWifi();
static const char*
ESActivateWifi();
}
-void ConnectToWiFiNetwork(const char *ssid, const char *pass, NetworkEventCallback cb)
+void ConnectToWiFiNetwork(const char *ssid, const char *pass,
+ ESEnrolleeNetworkEventCallback cb)
{
OIC_LOG_V(INFO, LOG_TAG, "ConnectToWiFiNetwork %s %s",ssid,pass);
gPass = pass;
*
* @param esResult ESResult provides the current state of the network connection status
*/
-typedef void (*NetworkEventCallback)(ESResult esResult);
+typedef void (*ESEnrolleeNetworkEventCallback)(ESResult esResult);
typedef struct
{
//byte mac[6];
} NetworkInfo;
-void ConnectToWiFiNetwork(const char *ssid, const char *pass, NetworkEventCallback);
+void ConnectToWiFiNetwork(const char *ssid, const char *pass,
+ ESEnrolleeNetworkEventCallback);
ESResult getCurrentNetworkInfo(OCConnectivityType targetType, NetworkInfo *info);
#endif
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-/**
- * @file
- *
- * This file contains the API declaration for creating & configuration for SoftAP
- */
+
#ifndef EASYSETUP_ENROLLEE_SOFTAP_H__
#define EASYSETUP_ENROLLEE_SOFTAP_H__
#define SOFTAP_SUCCESS 1
#define SOFTAP_FAILED 0
+/**
+ * @file
+ *
+ * This file contains the API declaration for creating & configuration for SoftAP
+ */
//This callback signagure may get changed as per the native implementation.
typedef void (*SoftAPCallbackNative)(int result, const char *ip, const char* mac_addr,
const char*device_name);
+/**
+ * This API creats the Soft AP using the platform specific native system calls.
+ * @Note This API to be implemented by the OEM if Enrollee device SoC supports SoftAP
+ *
+ * @param networkType NetworkType on which OnBoarding has to be performed.
+ * @param ssid SSID of the target SoftAP network to which the Enrollee is
+ * connecting.
+ * @param passwd Password of the target SoftAP network to which the Enrollee is
+ * connecting
+ * @param SoftAPCallbackNative EventCallback for for updating the Enrollee OnBoarding status
+ * result to the application
+ */
void ESCreateSoftapNative(const char * ssid, const char* passwd, SoftAPCallbackNative cb);
// Callback functions
//-----------------------------------------------------------------------------
extern "C" void EventCallbackInApplication(ESResult esResult,
- EnrolleeState enrolleeState)
+ ESEnrolleeState enrolleeState)
{
OIC_LOG(INFO, TAG, "Entering EventCallbackInApplication");
{
OIC_LOG(INFO, TAG, "Entering InitESEnrollee");
- EXPECT_EQ(ES_OK, InitEasySetup(CT_ADAPTER_IP,
+ EXPECT_EQ(ES_OK, ESInitEnrollee(CT_ADAPTER_IP,
"EasySetup123",
"EasySetup123",
0,
TEST(ESEnrolleeInit, ESEnrolleeInitNullSSID)
{
- EXPECT_EQ(ES_ERROR, InitEasySetup(CT_ADAPTER_IP, 0, passwd, 0, EventCallbackInApplication));
+ EXPECT_EQ(ES_ERROR, ESInitEnrollee(CT_ADAPTER_IP, 0, passwd, 0, EventCallbackInApplication));
}
TEST(ESEnrolleeInit, ESEnrolleeInitNullPassword)
{
- EXPECT_EQ(ES_ERROR, InitEasySetup(CT_ADAPTER_IP, ssid, 0, 0, EventCallbackInApplication));
+ EXPECT_EQ(ES_ERROR, ESInitEnrollee(CT_ADAPTER_IP, ssid, 0, 0, EventCallbackInApplication));
}
TEST(ESEnrolleeInit, ESEnrolleeInitNullCb)
{
- EXPECT_EQ(ES_ERROR, InitEasySetup(CT_ADAPTER_IP, ssid, passwd, 0, 0));
+ EXPECT_EQ(ES_ERROR, ESInitEnrollee(CT_ADAPTER_IP, ssid, passwd, 0, 0));
}
-TEST(ESEnrolleeInit, ESEnrolleeInitEasySetupSuccess)
+TEST(ESEnrolleeInit, ESEnrolleeESInitEnrolleeSuccess)
{
- EXPECT_EQ(ES_OK, InitEasySetup(CT_ADAPTER_IP,
+ EXPECT_EQ(ES_OK, ESInitEnrollee(CT_ADAPTER_IP,
ssid,
passwd,
0,
EXPECT_EQ(OC_STACK_ERROR, OCStop());
}
-TEST(ESProvisioning, ESInitProvisioning)
+TEST(ESProvisioning, ESInitProvisioningResource)
{
- EXPECT_EQ(ES_RESOURCECREATED, InitProvisioning());
+ EXPECT_EQ(ES_RESOURCECREATED, ESInitProvisioning());
}
TEST(ESProvisioning, ESInitProvisioningWithOCStackClientMode)
{
EXPECT_EQ(OC_STACK_OK, OCInit(NULL, 0, OC_CLIENT));
- EXPECT_EQ(ES_ERROR, InitProvisioning());
+ EXPECT_EQ(ES_ERROR, ESInitProvisioning());
EXPECT_EQ(OC_STACK_OK, OCStop());
}
TEST(ESOnboarding, ESOnboardingSoftAp)
{
- EXPECT_EQ(1, ESOnboard(ssid, passwd, OnboardingCallback));
+ EXPECT_EQ(1, ESOnboard(ssid, passwd, ESOnboardingCallback));
}
TEST(ESOnboarding, ESOnboardingSoftApEnrollee)
TEST(ESStop, ESTerminateEasysetupWithoutESInit)
{
- EXPECT_EQ(ES_ERROR, TerminateEasySetup());
+ EXPECT_EQ(ES_ERROR, ESTerminateEnrollee());
}
TEST(ESStop, ESTerminateEasysetupWithoutOCStack)
{
- EXPECT_EQ(ES_OK, InitEasySetup(CT_ADAPTER_IP,
+ EXPECT_EQ(ES_OK, ESInitEnrollee(CT_ADAPTER_IP,
ssid,
passwd,
0,
EventCallbackInApplication));
- EXPECT_EQ(ES_ERROR, TerminateEasySetup());
+ EXPECT_EQ(ES_ERROR, ESTerminateEnrollee());
}
TEST(ESStop, ESTerminateEasysetupWithOutCreateProvisioningResource)
{
- EXPECT_EQ(ES_OK, InitEasySetup(CT_ADAPTER_IP,
+ EXPECT_EQ(ES_OK, ESInitEnrollee(CT_ADAPTER_IP,
ssid,
passwd,
0,
EventCallbackInApplication));
EXPECT_EQ(OC_STACK_OK, OCInit(0, 0, OC_SERVER));
- EXPECT_EQ(ES_ERROR, TerminateEasySetup());
+ EXPECT_EQ(ES_ERROR, ESTerminateEnrollee());
EXPECT_EQ(OC_STACK_OK, OCStop());
}
TEST(ESStop, ESTerminateEasysetupWithoutProviosioningResource)
{
- EXPECT_EQ(ES_OK, InitEasySetup(CT_ADAPTER_IP,
+ EXPECT_EQ(ES_OK, ESInitEnrollee(CT_ADAPTER_IP,
ssid,
passwd,
0,
EventCallbackInApplication));
EXPECT_EQ(OC_STACK_OK, OCInit(NULL, 0, OC_SERVER));
- EXPECT_EQ(ES_ERROR, TerminateEasySetup());
+ EXPECT_EQ(ES_ERROR, ESTerminateEnrollee());
EXPECT_EQ(OC_STACK_OK, OCStop());
}
TEST(ESStop, ESTerminateEasysetupSuccess)
{
- EXPECT_EQ(ES_OK, InitEasySetup(CT_ADAPTER_IP,
+ EXPECT_EQ(ES_OK, ESInitEnrollee(CT_ADAPTER_IP,
ssid,
passwd,
0,
EventCallbackInApplication));
EXPECT_EQ(OC_STACK_OK, OCInit(NULL, 0, OC_SERVER));
- EXPECT_EQ(ES_RESOURCECREATED, InitProvisioning());
- EXPECT_EQ(ES_OK, TerminateEasySetup());
+ EXPECT_EQ(ES_RESOURCECREATED, ESInitProvisioning());
+ EXPECT_EQ(ES_OK, ESTerminateEnrollee());
EXPECT_EQ(OC_STACK_OK, OCStop());
}
* Enrollee moves to this state after connecting to target network
*/
ES_ON_BOARDED_TARGET_NETWORK_STATE,
-}EnrolleeState;
+}ESEnrolleeState;
/**
* Provisioning Device Status
easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
easy_setup_env.AppendUnique(CXXFLAGS = ['-pthread'])
- easy_setup_env.PrependUnique(LIBS = ['coap'])
- easy_setup_env.AppendUnique(LIBS = ['connectivity_abstraction'])
- easy_setup_env.AppendUnique(LIBS = ['oc_logger'])
- easy_setup_env.AppendUnique(LIBS = ['octbstack'])
- easy_setup_env.AppendUnique(LIBS = ['oc'])
- easy_setup_env.AppendUnique(LIBS = ['pthread'])
+ easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction'])
######################################################################
# Android Mediator
easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
easy_setup_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
- easy_setup_env.PrependUnique(LIBS = ['coap'])
- easy_setup_env.AppendUnique(LIBS = ['connectivity_abstraction'])
- easy_setup_env.AppendUnique(LIBS = ['oc_logger'])
- easy_setup_env.AppendUnique(LIBS = ['octbstack'])
- easy_setup_env.AppendUnique(LIBS = ['oc'])
- easy_setup_env.AppendUnique(LIBS = ['gnustl_shared'])
-
+ easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'gnustl_shared'])
if not env.get('RELEASE'):
easy_setup_env.AppendUnique(LIBS = ['log'])
};
//callbacks
-void OCProvisioningStatusCallback(EasySetupInfo *easySetupInfo) {
- OC_UNUSED(easySetupInfo);
+void OCProvisioningStatusCallback(EasySetupInfo *easySetupInfo)
+{
+ (void) easySetupInfo;
}
/* Test cases for prov_adapter*/
easy_setup_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x'])
if target_os in ['linux']:
- easy_setup_env.AppendUnique(LIBS = ['pthread', 'dl'])
+ easy_setup_env.AppendUnique(LIBS = ['pthread', 'dl', 'coap'])
if target_os in ['android']:
easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
easy_setup_env.AppendUnique(LIBPATH = [env.get('SRC_DIR')+'/android/android_api/base/libs/armeabi'])
easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
easy_setup_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
- easy_setup_env.PrependUnique(LIBS = ['coap'])
- easy_setup_env.AppendUnique(LIBS = ['connectivity_abstraction'])
- easy_setup_env.AppendUnique(LIBS = ['oc_logger'])
- easy_setup_env.AppendUnique(LIBS = ['octbstack'])
- easy_setup_env.AppendUnique(LIBS = ['oc'])
- easy_setup_env.AppendUnique(LIBS = ['gnustl_shared'])
+ easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'gnustl_shared'])
if env.get('SECURED') == '1':
easy_setup_env.AppendUnique(LIBS = ['ocpmapi','ocprovision'])
if not env.get('RELEASE'):
easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
easy_setup_env.AppendUnique(CXXFLAGS = ['-pthread'])
- easy_setup_env.PrependUnique(LIBS = ['coap'])
- easy_setup_env.AppendUnique(LIBS = ['connectivity_abstraction'])
- easy_setup_env.AppendUnique(LIBS = ['oc_logger'])
- easy_setup_env.AppendUnique(LIBS = ['octbstack'])
- easy_setup_env.AppendUnique(LIBS = ['oc'])
- easy_setup_env.AppendUnique(LIBS = ['pthread'])
+ easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger'])
if env.get('SECURED') == '1':
easy_setup_env.AppendUnique(LIBS = ['ocpmapi', 'ocprovision'])
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-/**
- * @file
- *
- * This file contains the declaration of exception classes for easy setup
- */
+
#ifndef EASY_SETUP_EXCEPTION_H
#define EASY_SETUP_EXCEPTION_H
#include <string>
#include <octypes.h>
-
+/**
+ * @file
+ *
+ * This file contains the declaration of exception classes for easy setup
+ */
namespace OIC
{
namespace Service
class ESPlatformException: public ESException
{
public:
+
+ /**
+ * Constructs an exception with a description.
+ *
+ * @param OCStackResult The description for the error.
+ */
explicit ESPlatformException(OCStackResult reason);
/**
OCStackResult getReasonCode() const;
/**
- * Returns the reason description.
+ * This function returns description of the exception.
*
*/
std::string getReason() const;
class ESBadRequestException: public ESException
{
public:
+ /**
+ * Constructs an exception with a description.
+ *
+ * @param OCStackResult The description for the error.
+ */
explicit ESBadRequestException(const std::string& what);
+ /**
+ * @overload
+ */
explicit ESBadRequestException(std::string&& what);
};
class ESInvalidParameterException: public ESException
{
public:
+ /**
+ * Constructs an exception with a description.
+ *
+ * @param OCStackResult The description for the error.
+ */
explicit ESInvalidParameterException(const std::string& what);
+ /**
+ * @overload
+ */
explicit ESInvalidParameterException(std::string&& what);
};
class ESBadGetException: public ESException
{
public:
+ /**
+ * Constructs an exception with a description.
+ *
+ * @param OCStackResult The description for the error.
+ */
explicit ESBadGetException(const std::string& what);
+ /**
+ * @overload
+ */
explicit ESBadGetException(std::string&& what);
};
class ESInvalidKeyException: public ESException
{
public:
+ /**
+ * Constructs an exception with a description.
+ *
+ * @param OCStackResult The description for the error.
+ */
explicit ESInvalidKeyException(const std::string& what);
+ /**
+ * @overload
+ */
explicit ESInvalidKeyException(std::string&& what);
};
}
/**
* This API is used for creating a remote Enrollee device instance.
- * @param enrolleeNWProvIndo Provisioning information for configuring the Enrollee.
+ * @param ProvConfig Provisioning information for configuring the Enrollee.
+ * @param WiFiOnboadingConnection Onboarding connection information for configuring the Enrollee.
*
* @throws ESBadRequestException If createEnrolleeDevice is invoked with the same
* provisioning information.
const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep,
const int eCode)
{
- OC_UNUSED(rep);
OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "checkProvInformationCb : %s, eCode = %d",
rep.getUri().c_str(),
eCode);
//callbacks
void easySetupStatusCallback (std::shared_ptr< EasySetupStatus > /*easySetupStatus*/)
{
+
+
}
/* Test cases for easysetyup class*/
if env.get('SECURED') == '1':
- mediator_rich_test_env.PrependUnique(LIBS = ['tinydtls','ocprovision', 'ocpmapi'])
+ mediator_rich_test_env.PrependUnique(LIBS = ['tinydtls','ocprovision', 'ocpmapi', 'timer'])
mediator_rich_test_env.PrependUnique(LIBS = [
- 'coap',
- 'connectivity_abstraction',
- 'oc_logger',
- 'oc_logger_core',
- 'octbstack',
- 'oc',
'ESMediatorRich',
+ 'oc',
+ 'octbstack',
+ 'oc_logger',
gtest,
gtest_main])
Serial.println("============");
}
-void EventCallbackInApp(ESResult esResult, EnrolleeState enrolleeState)
+void EventCallbackInApp(ESResult esResult, ESEnrolleeState enrolleeState)
{
Serial.println("callback!!! in app");
{
OIC_LOG(DEBUG, TAG, "OCServer is starting...");
- //InitEasySetup with sercurity mode disabled for arduino
- if(InitEasySetup(CT_ADAPTER_IP, ssid, passwd, false, EventCallbackInApp) == ES_ERROR)
+ //ESInitEnrollee with sercurity mode disabled for arduino
+ if(ESInitEnrollee(CT_ADAPTER_IP, ssid, passwd, false, EventCallbackInApp) == ES_ERROR)
{
OIC_LOG(ERROR, TAG, "OnBoarding Failed");
return;
OIC_LOG_V(ERROR, TAG, "OnBoarding succeded. Successfully connected to ssid : %s",ssid);
}
-void StartProvisioning()
+void ESInitResources()
{
- OIC_LOG(DEBUG, TAG, "StartProvisioning is invoked...");
+ OIC_LOG(DEBUG, TAG, "ESInitResources is invoked...");
// Initialize the OC Stack in Server mode
if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
return;
}
- if (InitProvisioning() == ES_ERROR)
+ if (ESInitProvisioning() == ES_ERROR)
{
OIC_LOG(ERROR, TAG, "Init Provisioning Failed!!");
return;
g_isInitialized = false;
- if (TerminateEasySetup() == ES_ERROR)
+ if (ESTerminateEnrollee() == ES_ERROR)
{
- OIC_LOG(ERROR, TAG, "TerminateEasySetup Failed!!");
+ OIC_LOG(ERROR, TAG, "ESTerminateEnrollee Failed!!");
return;
}
break;
case 'P': // start provisioning
- StartProvisioning();
+ ESInitResources();
break;
case 'T': // stop easy setup
if (WiFi.status() == WL_CONNECTED)
is_connected = true;
else if (is_connected)
- TerminateEasySetup();
+ ESTerminateEnrollee();
// Give CPU cycles to OCStack to perform send/recv and other OCStack stuff
if (OCProcess() != OC_STACK_OK)
printf("============\n");
}
-void EventCallbackInApp(ESResult esResult, EnrolleeState enrolleeState)
+void EventCallbackInApp(ESResult esResult, ESEnrolleeState enrolleeState)
{
printf("Easy setup event callback\n");
{
printf("StartEasySetup and onboarding started..\n");
- if(InitEasySetup(CT_ADAPTER_IP, ssid, passwd, gIsSecured, EventCallbackInApp) == ES_ERROR)
+ if(ESInitEnrollee(CT_ADAPTER_IP, ssid, passwd, gIsSecured, EventCallbackInApp) == ES_ERROR)
{
printf("StartEasySetup and onboarding Fail!!\n");
return;
}
}
-void StartOICStackAndStartResources()
+void ESInitResources()
{
printf("Starting Enrollee Provisioning\n");
return;
}
- if (InitProvisioning() == ES_ERROR)
+ if (ESInitProvisioning() == ES_ERROR)
{
printf("Init Provisioning Failed!!\n");
return;
printf("Thread creation failed\n");
}
- printf("InitProvisioning Success\n");
+ printf("ESInitProvisioning Success\n");
}
void StopEasySetup()
{
printf("StopEasySetup IN\n");
- if (TerminateEasySetup() == ES_ERROR)
+ if (ESTerminateEnrollee() == ES_ERROR)
{
- printf("TerminateEasySetup Failed!!\n");
+ printf("ESTerminateEnrollee Failed!!\n");
return;
}
printf("EasySetup Enrollee SAMPLE\n");
printf("#########################\n");
PrintMenu();
- char option = 'T';
+ char option = 'T';
while(true)
{
case 'P': // start provisioning
case 'p':
- StartOICStackAndStartResources();
+ ESInitResources();
break;
case 'T': // stop easy setup
cout<<"============"<<endl;
}
-void EventCallbackInApp(ESResult esResult, EnrolleeState enrolleeState)
+void EventCallbackInApp(ESResult esResult, ESEnrolleeState enrolleeState)
{
cout<<"Easy setup event callback"<<endl;
{
cout<<"StartEasySetup and onboarding started.."<<endl;
- if(InitEasySetup(CT_ADAPTER_IP, ssid, passwd, gIsSecured, EventCallbackInApp) == ES_ERROR)
+ if(ESInitEnrollee(CT_ADAPTER_IP, ssid, passwd, gIsSecured, EventCallbackInApp) == ES_ERROR)
{
cout<<"StartEasySetup and onboarding Fail!!"<<endl;
return;
}
}
-void StartOICStackAndStartResources()
+void ESInitResources()
{
cout<<"Starting Enrollee Provisioning"<<endl;
return;
}
- if (InitProvisioning() == ES_ERROR)
+ if (ESInitProvisioning() == ES_ERROR)
{
cout<<"Init Provisioning Failed!!"<<endl;
return;
cout<<"Thread creation failed"<<endl;
}
- cout<<"InitProvisioning Success"<<endl;
+ cout<<"ESInitProvisioning Success"<<endl;
}
void StopEasySetup()
{
cout<<"StopEasySetup IN"<<endl;
- if (TerminateEasySetup() == ES_ERROR)
+ if (ESTerminateEnrollee() == ES_ERROR)
{
- cout<<"TerminateEasySetup Failed!!"<<endl;
+ cout<<"ESTerminateEnrollee Failed!!"<<endl;
return;
}
case 'P': // start provisioning
case 'p':
- StartOICStackAndStartResources();
+ ESInitResources();
break;
case 'T': // stop easy setup
--- /dev/null
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "61646d69-6e44-6576-6963-655575696430"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "61646d69-6e44-6576-6963-655575696430",\r
+ "rowneruuid": "61646d69-6e44-6576-6963-655575696430",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "61646d69-6e44-6576-6963-655575696430",\r
+ "devowneruuid": "61646d69-6e44-6576-6963-655575696430",\r
+ "rowneruuid": "61646d69-6e44-6576-6963-655575696430",\r
+ "dpc": false\r
+ }\r
+}\r
if target_os not in ['windows', 'winrt']:
mediator_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x'])
-
+
mediator_env.PrependUnique(CPPPATH = [
env.get('SRC_DIR') + '/resource/include',
env.get('SRC_DIR') + '/resource/oc_logger/include',
- env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include',
+ env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include',
env.get('SRC_DIR') + '/resource/csdk/stack/include',
env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include',
env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal',
env.get('SRC_DIR') + '/service/easy-setup/mediator/richsdk/src',
env.get('SRC_DIR') + '/service/easy-setup/inc'])
-mediator_env.PrependUnique(LIBS = ['coap'])
-mediator_env.AppendUnique(LIBS = ['connectivity_abstraction'])
-mediator_env.AppendUnique(LIBS = ['oc_logger'])
-mediator_env.AppendUnique(LIBS = ['octbstack'])
-mediator_env.AppendUnique(LIBS = ['oc'])
-mediator_env.AppendUnique(LIBS = ['pthread'])
-mediator_env.AppendUnique(LIBS = ['ESMediatorRich'])
+if env.get('SECURED') == '1':
+ mediator_env.PrependUnique(LIBS = ['tinydtls', 'timer'])
+
+mediator_env.PrependUnique(LIBS = ['ESMediatorRich', 'oc', 'octbstack', 'oc_logger'])
if env.get('SECURED') == '1':
mediator_env.PrependUnique(LIBS = ['ocpmapi', 'ocprovision'])
void easySetupStatusCallback (std::shared_ptr< EasySetupStatus > easySetupStatus)
{
- OC_UNUSED(easySetupStatus);
OIC_LOG_V(DEBUG, ES_SAMPLE_APP_TAG, "easySetupStatusCallback status is Status = %d",
easySetupStatus->getEasySetupState());
remoteEnrollee->registerEasySetupStatusHandler(&easySetupStatusCallback);
}
-}
+}
void runEasySetupMenu()
{
constexpr int EASY_SETUP_INIT = 1;
m_mapInputData.clear();
if (!attributeName.compare("weight"))
- m_mapInputData.insert(std::make_pair("weight", values.back().toString()));
+ m_mapInputData.insert(std::make_pair("weight", values.back().get< std::string >()));
if (!attributeName.compare("height"))
- m_mapInputData.insert(std::make_pair("height", values.back().toString()));
+ m_mapInputData.insert(std::make_pair("height", values.back().get< std::string >()));
executeLogic();
}
}
}
- void Configuration::getResourceConfiguration(std::string bundleId, std::string resourceName,
+ void Configuration::getResourceConfiguration(std::string bundleId, std::string resourceUri,
resourceInfo *resourceInfoOut){
rapidxml::xml_node< char > *bundle;
rapidxml::xml_node< char > *resource;
string strBundleId;
string strKey, strValue;
OIC_LOG_V(INFO, CONTAINER_TAG, "Loading resource configuration for %s %s!",
- bundleId.c_str(), resourceName.c_str());
+ bundleId.c_str(), resourceUri.c_str());
if (m_loaded)
{
if (!strKey.compare(OUTPUT_RESOURCE_NAME))
{
- if (trim_both(strValue).compare(resourceName) != 0) break;
+
resourceInfoOut->name = trim_both(strValue);
}
else if (!strKey.compare(OUTPUT_RESOURCE_URI))
+ {
+ if (trim_both(strValue).compare(resourceUri) != 0)
+ {
+ break;
+ }
resourceInfoOut->uri = trim_both(strValue);
+ }
else if (!strKey.compare(OUTPUT_RESOURCE_ADDR))
resourceInfoOut->address = trim_both(strValue);
{
OIC_LOG_V(DEBUG, CONTAINER_TAG, "Discover input resource %s", outputResourceUri.c_str());
auto foundOutputResource = m_mapResources.find(outputResourceUri);
- // auto resourceProperty = foundOutputResource->second->m_mapResourceProperty;
resourceInfo info;
m_config->getResourceConfiguration(foundOutputResource->second->m_bundleId,
- foundOutputResource->second->m_name, &info);
+ outputResourceUri, &info);
map< string, vector< map< string, string > > > resourceProperty = info.resourceProperty;
try
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl"
- ],
- "perms": 2,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MjIyMjIyMjIyMjIyMjIyMg==",
- "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MTExMTExMTExMTExMTExMQ==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "32323232-3232-3232-3232-323232323232"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+ "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "31313131-3131-3131-3131-313131313131",\r
+ "credtype": 1,\r
+ "privatedata": {\r
+ "data": "AAAAAAAAAAAAAAAA",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "32323232-3232-3232-3232-323232323232"\r
+ }\r
+}
\ No newline at end of file
-{
- "acl": [
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/res",
- "/oic/d",
- "/oic/p",
- "/oic/res/types/d",
- "/oic/ad",
- "/oic/sec/acl"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": [
- "/oic/sec/doxm",
- "/oic/sec/pstat"
- ],
- "perms": 2,
- "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
- },
- {
- "sub": "Kg==",
- "rsrc": ["/a/light"],
- "perms": 6,
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }
- ],
- "pstat": {
- "isop": true,
- "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
- "ch": 0,
- "cm": 0,
- "tm": 0,
- "om": 3,
- "sm": [3]
- },
- "doxm": {
- "oxm": [0],
- "oxmsel": 0,
- "sct": 1,
- "owned": true,
- "deviceid": "MTExMTExMTExMTExMTExMQ==",
- "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
- },
- "cred": [{
- "credid": 1,
- "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
- "credtyp": 1,
- "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
- "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
- }]
-}
+{\r
+ "acl": {\r
+ "aclist": {\r
+ "aces": [\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/res",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/p",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/res/types/d",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/ad",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/oic/sec/acl",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/oic/sec/doxm",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ } ,\r
+ {\r
+ "href": "/oic/sec/pstat",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 2\r
+ },\r
+ {\r
+ "subjectuuid": "*",\r
+ "resources": [\r
+ {\r
+ "href": "/a/light",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/a/light0",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ },\r
+ {\r
+ "href": "/a/light1",\r
+ "rel": "",\r
+ "rt": "",\r
+ "if": ""\r
+ }\r
+ ],\r
+ "permission": 6\r
+ }\r
+ ]\r
+ },\r
+ "rowneruuid" : "31313131-3131-3131-3131-313131313131"\r
+ },\r
+ "pstat": {\r
+ "isop": true,\r
+ "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+ "cm": 0,\r
+ "tm": 0,\r
+ "om": 3,\r
+ "sm": 3\r
+ },\r
+ "doxm": {\r
+ "oxms": [0],\r
+ "oxmsel": 0,\r
+ "sct": 1,\r
+ "owned": true,\r
+ "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+ "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+ "dpc": false\r
+ },\r
+ "cred": {\r
+ "creds": [\r
+ {\r
+ "credid": 1,\r
+ "subjectuuid": "32323232-3232-3232-3232-323232323232",\r
+ "credtype": 1,\r
+ "privatedata": {\r
+ "data": "AAAAAAAAAAAAAAAA",\r
+ "encoding": "oic.sec.encoding.raw"\r
+ }\r
+ }\r
+ ],\r
+ "rowneruuid": "31313131-3131-3131-3131-313131313131"\r
+ }\r
+}\r
+\r
// Remove white spaces(if any) at the beginning
int beginning = 0;
int negative = 0;
- int invalidflag = 0;
+ int invalidFlag = 0;
while (attributeString[beginning] == ' ')
{
cp out/tizen/*/%{build_mode}/resource/examples/simpleserver %{ex_install_dir}
cp out/tizen/*/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir}
cp out/tizen/*/%{build_mode}/resource/examples/threadingsample %{ex_install_dir}
-cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_server.json %{ex_install_dir}
-cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_client.json %{ex_install_dir}
+cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_server.dat %{ex_install_dir}
+cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_client.dat %{ex_install_dir}
cp out/tizen/*/%{build_mode}/libcoap.a %{buildroot}%{_libdir}
%if 0%{?SECURED} == 1
mkdir -p %{ex_install_dir}/provisioning