#ifndef OC_SECURITY_RESOURCE_TYPES_H
#define OC_SECURITY_RESOURCE_TYPES_H
+#include "iotivity_config.h"
+
#include <stdint.h> // for uint8_t typedef
#include <stdbool.h>
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#include "byte_array.h"
+#endif /* __WITH_DTLS__ or __WITH_TLS__*/
#ifdef __cplusplus
extern "C" {
#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)
#define SUBJECT_NOT_FOUND_DEF (1 << 3)
#define RESOURCE_NOT_FOUND_DEF (1 << 4)
#define POLICY_ENGINE_ERROR_DEF (1 << 5)
+#define INVALID_PERIOD_DEF (1 << 6)
+#define ACCESS_WAITING_DEF (1 << 7)
+#define AMS_SERVICE_DEF (1 << 8)
#define REASON_MASK_DEF (INSUFFICIENT_PERMISSION_DEF | \
+ INVALID_PERIOD_DEF | \
SUBJECT_NOT_FOUND_DEF | \
RESOURCE_NOT_FOUND_DEF | \
POLICY_ENGINE_ERROR_DEF)
{
ACCESS_GRANTED = ACCESS_GRANTED_DEF,
ACCESS_DENIED = ACCESS_DENIED_DEF,
+ ACCESS_DENIED_INVALID_PERIOD = ACCESS_DENIED_DEF
+ | INVALID_PERIOD_DEF,
ACCESS_DENIED_INSUFFICIENT_PERMISSION = ACCESS_DENIED_DEF
| INSUFFICIENT_PERMISSION_DEF,
ACCESS_DENIED_SUBJECT_NOT_FOUND = ACCESS_DENIED_DEF
| RESOURCE_NOT_FOUND_DEF,
ACCESS_DENIED_POLICY_ENGINE_ERROR = ACCESS_DENIED_DEF
| POLICY_ENGINE_ERROR_DEF,
+ ACCESS_WAITING_FOR_AMS = ACCESS_WAITING_DEF
+ | AMS_SERVICE_DEF,
+ ACCESS_DENIED_AMS_SERVICE_ERROR = ACCESS_DENIED
+ | AMS_SERVICE_DEF
} SRMAccessResponse_t;
/**
/**
* Extract Reason Code from Access Response.
*/
-static inline SRMAccessResponseReasonCode_t GetReasonCode(
+INLINE_API SRMAccessResponseReasonCode_t GetReasonCode(
SRMAccessResponse_t response)
{
SRMAccessResponseReasonCode_t reason =
/**
* Returns 'true' iff request should be passed on to RI layer.
*/
-static inline bool IsAccessGranted(SRMAccessResponse_t response)
+INLINE_API bool IsAccessGranted(SRMAccessResponse_t response)
{
if(ACCESS_GRANTED == (response & ACCESS_GRANTED))
{
}
}
+typedef struct OicSecRsrc OicSecRsrc_t;
+
+typedef struct OicSecValidity OicSecValidity_t;
+
+typedef struct OicSecAce OicSecAce_t;
+
typedef struct OicSecAcl OicSecAcl_t;
typedef struct OicSecAmacl OicSecAmacl_t;
typedef struct OicSecCred OicSecCred_t;
/**
- * @brief /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
- * 4: asymmetric key
- * 8: signed asymmetric key (aka certificate)
- * 16: PIN /password
- */
-typedef uint16_t OicSecCredType_t;
-
-/**
* Aid for assigning/testing vals with OicSecCredType_t.
* Example:
* OicSecCredType_t ct = PIN_PASSWORD | ASYMMETRIC_KEY;
ASYMMETRIC_KEY = (0x1 << 2),
SIGNED_ASYMMETRIC_KEY = (0x1 << 3),
PIN_PASSWORD = (0x1 << 4),
+ ASYMMETRIC_ENCRYPTION_KEY = (0x1 << 5),
} OSCTBitmask_t;
+/**
+ * /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
+ * 4: asymmetric key
+ * 8: signed asymmetric key (aka certificate)
+ * 16: PIN /password
+ */
+typedef OSCTBitmask_t OicSecCredType_t;
+
typedef struct OicSecDoxm OicSecDoxm_t;
typedef enum OicSecDpm
SECURITY_MANAGEMENT_SERVICES = (0x1 << 3),
PROVISION_CREDENTIALS = (0x1 << 4),
PROVISION_ACLS = (0x1 << 5),
- // << 6 THROUGH 15 RESERVED
+#ifdef MULTIPLE_OWNER
+ TAKE_SUB_OWNER = (0x1 << 6),
+#endif
+ // << 7 THROUGH 15 RESERVED
} OicSecDpm_t;
+// These types are taken from the Security Spec v1.1.12 /pstat resource definition
+// Note that per the latest spec, there is NO definition for Multiple Service Client Directed
+// provisioning mode, so that enum value has been removed.
typedef enum OicSecDpom
{
- MULTIPLE_SERVICE_SERVER_DRIVEN = 0x0,
- SINGLE_SERVICE_SERVER_DRIVEN = 0x1,
- MULTIPLE_SERVICE_CLIENT_DRIVEN = 0x2,
- SINGLE_SERVICE_CLIENT_DRIVEN = 0x3,
+ MULTIPLE_SERVICE_SERVER_DRIVEN = (0x1 << 0),
+ SINGLE_SERVICE_SERVER_DRIVEN = (0x1 << 1),
+ SINGLE_SERVICE_CLIENT_DRIVEN = (0x1 << 2),
} OicSecDpom_t;
-typedef enum OicSecSvcType
-{
- SERVICE_UNKNOWN = 0x0,
- ACCESS_MGMT_SERVICE = 0x1, //urn:oic.sec.ams
-} OicSecSvcType_t;
-
-
//TODO: Need more clarification on deviceIDFormat field type.
#if 0
typedef enum
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_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_MODE_SWITCH = 0x1,
- OIC_RANDOM_DEVICE_PIN = 0x2,
- OIC_PRE_PROVISIONED_DEVICE_PIN = 0x3,
- OIC_PRE_PROVISION_STRONG_CREDENTIAL = 0x4
+ OIC_RANDOM_DEVICE_PIN = 0x1,
+ OIC_MANUFACTURER_CERTIFICATE = 0x2,
+ OIC_DECENTRALIZED_PUBLIC_KEY = 0x3,
+ OIC_OXM_COUNT,
+#ifdef MULTIPLE_OWNER
+ OIC_PRECONFIG_PIN = 0xFF00,
+#endif //MULTIPLE_OWNER
+ OIC_MV_JUST_WORKS = 0xFF01,
+ OIC_CON_MFG_CERT = 0xFF02,
}OicSecOxm_t;
-typedef struct OicSecJwk OicSecJwk_t;
+typedef enum
+{
+ OIC_ENCODING_UNKNOW = 0,
+ OIC_ENCODING_RAW = 1,
+ OIC_ENCODING_BASE64 = 2,
+ OIC_ENCODING_PEM = 3,
+ OIC_ENCODING_DER = 4
+}OicEncodingType_t;
+
+#ifdef MULTIPLE_OWNER
+typedef enum
+{
+ MOT_STATUS_READY = 0,
+ MOT_STATUS_IN_PROGRESS = 1,
+ MOT_STATUS_DONE = 2,
+}MotStatus_t;
+#endif //MULTIPLE_OWNER
+
+/*
+ * oic.sec.mom type definition
+ * TODO: This type will be included to OIC Security Spec.
+ * 0 : Disable multiple owner
+ * 1 : Enable multiple owner (Always on)
+ * 2 : Timely multiple owner enable
+ */
+typedef enum
+{
+ OIC_MULTIPLE_OWNER_DISABLE = 0,
+ OIC_MULTIPLE_OWNER_ENABLE = 1,
+ OIC_MULTIPLE_OWNER_TIMELY_ENABLE = 2,
+ OIC_NUMBER_OF_MOM_TYPE = 3
+}OicSecMomType_t;
+
+typedef struct OicSecKey OicSecKey_t;
+
+typedef struct OicSecOpt OicSecOpt_t;
typedef struct OicSecPstat OicSecPstat_t;
typedef struct OicSecSacl OicSecSacl_t;
-typedef struct OicSecSvc OicSecSvc_t;
-
typedef char *OicUrn_t; //TODO is URN type defined elsewhere?
typedef struct OicUuid OicUuid_t; //TODO is UUID type defined elsewhere?
+#ifdef MULTIPLE_OWNER
+typedef struct OicSecSubOwner OicSecSubOwner_t;
+typedef struct OicSecMom OicSecMom_t;
+#endif //MULTIPLE_OWNER
+
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+typedef struct OicSecCrl OicSecCrl_t;
+typedef ByteArray_t OicSecCert_t;
+#else
+typedef void OicSecCert_t;
+#endif /* __WITH_DTLS__ or __WITH_TLS__*/
/**
- * @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;
+
+ // TODO: This field added as workaround. Will be replaced soon.
+ OicEncodingType_t encoding;
+
+};
+
+struct OicSecOpt
+{
+ uint8_t *data;
+ size_t len;
+
+ OicEncodingType_t encoding;
+ bool revstat;
+};
+
+struct OicSecRsrc
+{
+ char *href; // 0:R:S:Y:String
+ char *rel; // 1:R:S:N:String
+ char** types; // 2:R:S:N:String Array
+ size_t typeLen; // the number of elts in types
+ char** interfaces; // 3:R:S:N:String Array
+ size_t interfaceLen; // the number of elts in interfaces
+ OicSecRsrc_t *next;
+};
+
+struct OicSecValidity
+{
+ char* period; // 0:R:S:Y:String
+ char** recurrences; // 1:R:M:Y:Array of String
+ size_t recurrenceLen; // the number of elts in recurrence
+ OicSecValidity_t *next;
+};
+
+struct OicSecAce
+{
+ // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+ OicUuid_t subjectuuid; // 0:R:S:Y:uuid
+ OicSecRsrc_t *resources; // 1:R:M:Y:Resource
+ uint16_t permission; // 2:R:S:Y:UINT16
+ OicSecValidity_t *validities; // 3:R:M:N:Time-interval
+#ifdef MULTIPLE_OWNER
+ OicUuid_t* eownerID; //4:R:S:N:oic.uuid
+#endif
+ OicSecAce_t *next;
};
/**
- * @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
{
// <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
- OicUuid_t subject; // 0:R:S:Y:uuid TODO: this deviates
- // from spec and needs to be updated
- // in spec (where it's a String).
- size_t resourcesLen; // the number of elts in Resources
- char **resources; // 1:R:M:Y:String
- uint16_t permission; // 2:R:S:Y:UINT16
- size_t periodsLen; // 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
- OicSecAcl_t *next;
+ OicUuid_t rownerID; // 0:R:S:Y:oic.uuid
+ OicSecAce_t *aces; // 1:R:M:N:ACE
};
/**
- * @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
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+ OicSecKey_t publicData; // own cerificate chain
+ char *credUsage; // 4:R:S:N:String
+ OicSecOpt_t optionalData; // CA's cerificate chain
+#endif /* __WITH_DTLS__ or __WITH_TLS__*/
+ 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
+#ifdef MULTIPLE_OWNER
+ OicUuid_t *eownerID; //9:R:S:N:oic.uuid
+#endif //MULTIPLE_OWNER
OicSecCred_t *next;
};
+#ifdef MULTIPLE_OWNER
+struct OicSecSubOwner {
+ OicUuid_t uuid;
+ MotStatus_t status;
+ OicSecSubOwner_t* next;
+};
+
+struct OicSecMom{
+ OicSecMomType_t mode;
+};
+#endif //MULTIPLE_OWNER
+
/**
- * @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
{
OicSecOxm_t *oxm; // 1:R:M:N:UINT16
size_t oxmLen; // the number of elts in Oxm
OicSecOxm_t oxmSel; // 2:R/W:S:Y:UINT16
- bool owned; // 3:R:S:Y:Boolean
+ OicSecCredType_t sct; // 3:R:S:Y:oic.sec.credtype
+ bool owned; // 4:R:S:Y:Boolean
//TODO: Need more clarification on deviceIDFormat field type.
- //OicSecDvcIdFrmt_t deviceIDFormat; // 4:R:S:Y:UINT8
- OicUuid_t deviceID; // 5:R:S:Y:oic.uuid
- OicUuid_t owner; // 6: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 Owner; // 5:R:S:Y:oic.sec.svc
- //TODO change Owner type to oic.sec.svc
+ //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; // 8:R:S:Y:oic.uuid
+#ifdef MULTIPLE_OWNER
+ OicSecSubOwner_t* subOwners; //9:R/W:M:N:oic.uuid
+ OicSecMom_t *mom; //10:R/W:S:N:oic.sec.mom
+#endif //MULTIPLE_OWNER
+ OicUuid_t rownerID; // 11:R:S:Y:oic.uuid
};
/**
- * @brief /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.
+ * /oic/sec/pstat (Provisioning Status) data type.
*/
struct OicSecPstat
{
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
{
// <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
//TODO fill in from OIC Security Spec
+#if defined(_MSC_VER)
+ uint8_t unused; // VS doesn't like empty structs
+#endif
+};
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+struct OicSecCrl
+{
+ uint16_t CrlId;
+ ByteArray_t ThisUpdate;
+ OicSecKey_t CrlData;
};
+#endif /* __WITH_DTLS__ or __WITH_TLS__ */
+
+/**
+ * @brief direct pairing data type
+ */
+typedef struct OicPin OicDpPin_t;
+
+typedef struct OicSecPdAcl OicSecPdAcl_t;
+
+typedef struct OicSecPconf OicSecPconf_t;
+
+typedef struct OicSecDpairing OicSecDpairing_t;
+
+#define DP_PIN_LENGTH 8 // temporary length
+
+/**
+ * @brief /oic/sec/prmtype (Pairing Method Type) data type.
+ * 0: not allowed
+ * 1: pre-configured pin
+ * 2: random pin
+ */
+typedef enum PRMBitmask
+{
+ PRM_NOT_ALLOWED = 0x0,
+ PRM_PRE_CONFIGURED = (0x1 << 0),
+ PRM_RANDOM_PIN = (0x1 << 1),
+} PRMBitmask_t;
+
+typedef PRMBitmask_t OicSecPrm_t;
+
+
+struct OicPin
+{
+ uint8_t val[DP_PIN_LENGTH];
+};
+
+/**
+ * @brief oic.sec.dpacltype (Device Pairing Access Control List) data type.
+ */
+struct OicSecPdAcl
+{
+ // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+ char **resources; // 0:R:M:Y:String
+ size_t resourcesLen; // the number of elts in Resources
+ uint16_t permission; // 1:R:S:Y:UINT16
+ char **periods; // 2:R:M*:N:String (<--M*; see Spec)
+ char **recurrences; // 3:R:M:N:String
+ size_t prdRecrLen; // the number of elts in Periods/Recurrences
+ OicSecPdAcl_t *next;
+};
+
+/**
+ * @brief /oic/sec/pconf (Pairing Configuration) data type
+ */
+struct OicSecPconf
+{
+ // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
+ bool edp; // 0:W:S:M:Boolean
+ OicSecPrm_t *prm; // 1:R:M:N:UINT16
+ size_t prmLen; // the number of elts in Prm
+ OicDpPin_t pin; // 2:R:S:Y:String
+ OicSecPdAcl_t *pdacls; // 3:R:M:Y:oic.sec.pdacltype
+ 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 rownerID; // 6:R:S:Y:oic.uuid
+};
+
+/**
+ * @brief /oic/sec/dpairing (Device Pairing) data type
+ */
+struct OicSecDpairing
+{
+ // <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 rownerID; // 2:R:S:Y:oic.uuid
+};
+
+#define OIC_SEC_MAX_VER_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/svc (Service requiring a secure connection) data type.
- * Derived from OIC Security Spec; see Spec for details.
+ * @brief /oic/sec/ver (Security Version) data type
*/
-struct OicSecSvc
+struct OicSecVer
{
// <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
- OicUuid_t svcdid; //0:R:S:Y:oic.uuid
- OicSecSvcType_t svct; //1:R:M:Y:OIC Service Type
- size_t ownersLen; //2:the number of elts in Owners
- OicUuid_t *owners; //3:R:M:Y:oic.uuid
- OicSecSvc_t *next;
+ char secv[OIC_SEC_MAX_VER_LEN]; // 0:R:S:Y:String
+ OicUuid_t deviceID; // 1:R:S:Y:oic.uuid
};
#ifdef __cplusplus