Commit d89db3ea authored by Heewon Park's avatar Heewon Park Committed by Uze Choi

[Update] process of provisioning was split.

Previously, Easy Setup for Mediator provided only 1 API, startProvisioning,
which was responsible for whole processes of easy setup.
We thought this approach had a limitation in case of user interaction required scenarios.
For this reason, we provide multiple APIs rather than a single API and
each of the processes of easy setup is as follows:

1. Discovery
2. SecurityProvisioning
3. Request Enrollee's resources
4. Data Provisioning (WiFi AP, device configuration information)
5. Cloud data provisioning (Auth Code, not implemented yet)

Change-Id: I172b9130531a0bb9e5b0f74aaee40a07523dcbd0
Signed-off-by: default avatarHeewon Park <h_w.park@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/8427Tested-by: default avatarjenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: default avatarUze Choi <uzchoi@samsung.com>
parent 6f6aa08d
......@@ -65,17 +65,17 @@ if target_os not in ['windows', 'winrt']:
if target_os in ['linux']:
easy_setup_env.AppendUnique(LIBS = ['pthread', 'dl', 'coap'])
if target_os in ['android']:
easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
if env.get('SECURED') == '1':
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 = ['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(LIBS = ['log'])
#if target_os in ['android']:
# easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
# if env.get('SECURED') == '1':
# 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 = ['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(LIBS = ['log'])
if target_os in ['linux']:
easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
......@@ -85,7 +85,8 @@ if target_os in ['linux']:
if env.get('SECURED') == '1':
easy_setup_env.AppendUnique(LIBS = ['ocpmapi', 'ocprovision'])
if target_os in ['android','linux']:
#if target_os in ['android','linux']:
if target_os in ['linux']:
easy_setup_env.PrependUnique(CPPPATH = [
env.get('SRC_DIR') + '/resource/c_common/oic_malloc/include',
env.get('SRC_DIR') + '/resource/include',
......@@ -113,12 +114,13 @@ print"easysetup_path %s" % easysetup_path
es_src = None
if target_os in ['android','linux']:
#if target_os in ['android','linux']:
if target_os in ['linux']:
if env.get('SECURED') == '1':
env.AppendUnique(es_src = [os.path.join(easysetup_path, 'src/EnrolleeSecurity.cpp')])
es_common_src = ['src/RemoteEnrollee.cpp',
'src/RemoteEnrolleeResource.cpp',
'src/EnrolleeResource.cpp',
'src/EasySetup.cpp',
'src/ESException.cpp']
......@@ -132,12 +134,12 @@ print "Files path is %s" % env.get('es_src')
######################################################################
# Build RichSDK Mediator Sample App
################################################ ######################
if target_os == 'linux':
SConscript('../../sampleapp/mediator/linux/richsdk_sample/SConscript')
#if target_os == 'linux':
# SConscript('../../sampleapp/mediator/linux/richsdk_sample/SConscript')
######################################################################
#Build UnitTestcases for Mediator[RichSDK]
################################################ ######################
if target_os == 'linux':
SConscript('unittests/SConscript')
#if target_os == 'linux':
# SConscript('unittests/SConscript')
......@@ -38,6 +38,7 @@ using namespace std;
#define IP_PORT 55555
#define NET_WIFI_SSID_SIZE 100
#define NET_WIFI_PWD_SIZE 100
#define NET_WIFI_AUTH_SIZE 100
/**
* @brief Mac address length for BT port
......@@ -47,19 +48,33 @@ using namespace std;
/**
* Attributes used to form a proper easysetup conforming JSON message.
*/
#define OC_RSRVD_ES_PS "ps"
#define OC_RSRVD_ES_TNN "tnn"
#define OC_RSRVD_ES_CD "cd"
#define OC_RSRVD_ES_TR "tr"
#define OC_RSRVD_ES_TNT "tnt"
#define OC_RSRVD_ES_ANT "ant"
#define OC_RSRVD_ES_PROVSTATUS "ps"
#define OC_RSRVD_ES_TRIGGER "tr"
#define OC_RSRVD_ES_SSID "tnn"
#define OC_RSRVD_ES_CRED "cd"
#define OC_RSRVD_ES_AUTHTYPE "wat"
#define OC_RSRVD_ES_ENCTYPE "wet"
#define OC_RSRVD_ES_AUTHCODE "ac"
#define OC_RSRVD_ES_AUTHPROVIDER "apn"
#define OC_RSRVD_ES_CISERVER "cisurl"
#define OC_RSRVD_ES_DEVNAME "dn"
#define OC_RSRVD_ES_LANGUAGE "lang"
#define OC_RSRVD_ES_COUNTRY "cont"
#define OC_RSRVD_ES_TNT "tnt"
#define OC_RSRVD_ES_ANT "ant"
/**
* Easysetup defined resoruce types and uris.
*/
#define OC_RSRVD_ES_PROV_RES_TYPE "oic.r.prov"
#define OC_RSRVD_ES_URI_PROV "/oic/prov"
#define OC_RSRVD_ES_URI_NET "/oic/net"
#define OC_RSRVD_ES_PROV_RES_TYPE "oic.r.prov"
#define OC_RSRVD_ES_URI_PROV "/.well-known/ocf/prov"
#define OC_RSRVD_ES_RES_TYPE_WIFI "ocf.r.wifi"
#define OC_RSRVD_ES_URI_WIFI "/.well-known/ocf/prov/wifi"
#define OC_RSRVD_ES_RES_TYPE_CLOUDSERVER "ocf.r.cloudserver"
#define OC_RSRVD_ES_URI_CLOUDSERVER "/.well-known/ocf/prov/cloudserver"
#define OC_RSRVD_ES_RES_TYPE_DEVCONF "ocf.r.devconf"
#define OC_RSRVD_ES_URI_DEVCONF "/.well-known/ocf/prov/devconf"
#define OC_RSRVD_ES_URI_NET "/oic/net"
/**
* @brief Defines for Provisioning status accepted values
......@@ -74,26 +89,6 @@ namespace OIC
{
namespace Service
{
/**
* Device Roles defined for each device type used in easy setup
*/
typedef enum
{
ENROLLEE,
MEDIATOR,
ENROLLER,
} DeviceRole;
/**
* On-boarding connection to create Adhoc network.
*/
typedef enum
{
SOFTAP,
BLE,
} OBConnection;
typedef enum
{
ES_ERROR = -1,
......@@ -106,70 +101,9 @@ namespace OIC
ES_RECVREQOFNETRES,
ES_RECVUPDATEOFPROVRES,
ES_RECVTRIGGEROFPROVRES,
ES_UNAUTHORIZED = 31
} ESResult;
typedef enum
{
/**
* Default state of the device
*/
ES_INIT_STATE,
/**
* Device will move to this state once the on boarding begins
*/
ES_ON_BOARDING_STATE,
/**
* Device will move to this state after successful on-boarding of the device
*/
ES_ON_BOARDED_STATE,
/**
* Device will move to this state once the on boarding is done
*/
ES_PROVISIONING_STATE,
/**
* Easy setup process is successful.
*/
ES_PROVISIONED_STATE,
/**
* This state is arbitrary one, any time device can come into this state
* Device will move to this state if the ownership transfer initiated by the Application
*/
ES_OWNERSHIP_TRANSFERRING_STATE,
/**
* This state is arbitrary one, any time device can come into this state
* Device will move to this state if the ownership transfer is completed
*/
ES_OWNERSHIP_TRANSFERRED_STATE,
/**
* This state is arbitrary one, any time device can come into this state
* Device will move to this state once the Application factory reset the device
*/
ES_FACTORY_RESET_STATE,
/**
* Enrollee moves to this state after connecting to target network
*/
ES_ON_BOARDED_TARGET_NETWORK_STATE,
}EnrolleeState;
/**
* Provisioning Device Status
*/
typedef struct
{
// Address of remote server
OCDevAddr * addr;
// Indicates adaptor type on which the response was received
OCConnectivityType connType;
} EasySetupDeviceInfo;
/**
* Provosioning Status
*/
......@@ -179,18 +113,31 @@ namespace OIC
DEVICE_NOT_PROVISIONED,
DEVICE_OWNED,
DEVICE_NOT_OWNED
} EasySetupState, ProvStatus;
} EasySetupState;
/**
* Response from queries to remote servers.
* @brief WIFI Authentication type of the Enroller
*/
typedef struct
typedef enum
{
// EasySetup Status
EasySetupState provStatus;
// EasySetup Device Info
EasySetupDeviceInfo provDeviceInfo;
} EasySetupInfo, ProvisioningInfo;
NONE_AUTH = 0,
WEP,
WPA_PSK,
WPA2_PSK
} WIFI_AUTHTYPE;
/**
* @brief WIFI ecnrytion type of the Enroller
*/
typedef enum
{
NONE_ENC = 0,
WEP_64,
WEP_128,
TKIP,
AES,
TKIP_AES
} WIFI_ENCTYPE;
/**
* @brief Network information of the Enroller
......@@ -220,6 +167,11 @@ namespace OIC
{
char ssid[NET_WIFI_SSID_SIZE]; /**< ssid of the Enroller**/
char pwd[NET_WIFI_PWD_SIZE]; /**< pwd of the Enroller**/
WIFI_AUTHTYPE authtype; /**< auth type of the Enroller**/
WIFI_ENCTYPE enctype; /**< encryption type of the Enroller**/
char authcode[NET_WIFI_AUTH_SIZE];
char authserverUrl[NET_WIFI_AUTH_SIZE];
char apiserverUrl[NET_WIFI_AUTH_SIZE];
} WIFI;
} ProvData;
......@@ -232,23 +184,6 @@ namespace OIC
OCConnectivityType connType; /**< Connectivity Type**/
} ProvConfig;
/**
* Client applications implement this callback to consume responses received from Servers.
*/
typedef void (*OCProvisioningStatusCB)(EasySetupInfo *easySetupInfo);
/**
* @brief This structure represent configuration information to create wifi onboarding SoftAP or connection.
*/
// Note : Below structure is not currently used but added for future purpose.
typedef struct
{
char ssid[NET_WIFI_SSID_SIZE]; /**< ssid of the onboarding Adhoc Wifi network**/
char pwd[NET_WIFI_PWD_SIZE]; /**< pwd of the onboarding Adhoc wifi network**/
bool isSecured; /**< Secure connection**/
}WiFiOnboardingConfig;
/**
* @brief This structure represent onboarding connection instance.
*/
......@@ -287,11 +222,10 @@ namespace OIC
/**
* Security Provisioning Status
*/
class SecProvisioningResult
class SecProvisioningStatus
{
public:
std::shared_ptr< SecProvisioningResult > shared_ptr;
SecProvisioningResult(std::string deviceUUID, ESResult result) :
SecProvisioningStatus(std::string deviceUUID, ESResult result) :
m_devUUID(deviceUUID), m_result(result)
{
......@@ -311,25 +245,56 @@ namespace OIC
ESResult m_result;
};
/**
* Callback function definition for providing Enrollee security status .
*/
typedef std::function< void(std::shared_ptr<SecProvisioningResult>) > EnrolleeSecStatusCb;
class CapabilityData
{
public:
CapabilityData()
{
/**
* Callback definition to be invoked when the security stack expects a pin from application.
*/
typedef std::function< void(std::string&) > SecurityPinCb;
}
private:
};
/**
* Callback definition to be invoked when the stack expects a db path.
*/
typedef std::function< void(std::string&) > SecProvisioningDbPathCb;
class InitRemoteEnrolleeStatus
{
public:
InitRemoteEnrolleeStatus(ESResult result) :
m_result(result)
{
}
ESResult getESResult()
{
return m_result;
}
private:
ESResult m_result;
};
class RequestCapabilityStatus
{
public:
RequestCapabilityStatus(ESResult result, const CapabilityData& data) :
m_result(result), m_capabilityData(data)
{
}
ESResult getESResult()
{
return m_result;
}
CapabilityData getCapabilityData()
{
return m_capabilityData;
}
private:
ESResult m_result;
CapabilityData m_capabilityData;
};
class ProvisioningStatus
{
public:
std::shared_ptr< ProvisioningStatus > shared_ptr;
ProvisioningStatus(ESResult result, ESState esState) :
m_result(result), m_esState(esState)
{
......@@ -353,7 +318,6 @@ namespace OIC
class EasySetupStatus
{
public:
std::shared_ptr< EasySetupStatus > shared_ptr;
EasySetupStatus(const EasySetupState& easySetupState,
const ProvConfig& provConfig) :
m_easySetupState(easySetupState), m_ProvConfig(provConfig)
......@@ -374,6 +338,36 @@ namespace OIC
EasySetupState m_easySetupState;
ProvConfig m_ProvConfig;
};
/**
* Callback function definition for providing Enrollee security status .
*/
typedef std::function< void(std::shared_ptr< InitRemoteEnrolleeStatus >) > InitRemoteEnrolleeStatusCb;
/**
* Callback function definition for providing Enrollee security status .
*/
typedef std::function< void(std::shared_ptr< RequestCapabilityStatus >) > RequestCapabilityStatusCb;
/**
* Callback function definition for providing Enrollee security status .
*/
typedef std::function< void(std::shared_ptr< ProvisioningStatus >) > DataProvStatusCb;
/**
* Callback function definition for providing Enrollee security status .
*/
typedef std::function< void(std::shared_ptr<SecProvisioningStatus>) > EnrolleeSecStatusCb;
/**
* Callback definition to be invoked when the security stack expects a pin from application.
*/
typedef std::function< void(std::string&) > SecurityPinCb;
/**
* Callback definition to be invoked when the stack expects a db path.
*/
typedef std::function< void(std::string&) > SecProvisioningDbPathCb;
}
}
#endif //WITH_ARDUINO
......
......@@ -50,8 +50,7 @@ namespace OIC
static EasySetup* getInstance();
/**
* This API is used for creating a remote Enrollee device instance.
* @param ProvConfig Provisioning information for configuring the Enrollee.
* This API is used for creating a remote Enrollee instance.
* @param WiFiOnboadingConnection Onboarding connection information for configuring the Enrollee.
*
* @throws ESBadRequestException If createEnrolleeDevice is invoked with the same
......@@ -59,20 +58,12 @@ namespace OIC
*
* @return Pointer to RemoteEnrollee instance.
*/
std::shared_ptr<RemoteEnrollee> createEnrolleeDevice (
const ProvConfig& enrolleeNWProvInfo,
const WiFiOnboadingConnection& wifiOnboardingconn);
std::shared_ptr<RemoteEnrollee> createRemoteEnrollee(const WiFiOnboadingConnection& wifiOnboardingconn);
private:
EasySetup();
~EasySetup();
RemoteEnrollee::shared_ptr findDeviceInProvisioningList(
const ProvConfig& enrolleeNWProvInfo,
const WiFiOnboadingConnection& wifiOnboardingconn);
bool addDeviceToProvisioningList(const RemoteEnrollee::shared_ptr remoteEnrollee);
bool deleteDeviceFromProvisioningList (const ProvConfig& enrolleeNWProvInfo);
std::vector< RemoteEnrollee::shared_ptr > m_activeEnrolleeList;
static EasySetup *s_instance;
};
}
......
......@@ -18,8 +18,8 @@
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#ifndef REMOTE_ENROLLEE_RESOURCE_H_
#define REMOTE_ENROLLEE_RESOURCE_H_
#ifndef ENROLLEE_RESOURCE_H_
#define ENROLLEE_RESOURCE_H_
#include <mutex>
#include <memory>
......@@ -40,28 +40,26 @@ namespace OIC
/**
* This class contains the resource discovery methods.
*
* @see RemoteEnrolleeResource
* @see EnrolleeResource
*/
class RemoteEnrolleeResource
class EnrolleeResource
{
friend class EnrolleeSecurity;
public:
typedef std::shared_ptr< RemoteEnrolleeResource > Ptr;
typedef std::function< void(std::shared_ptr< ProvisioningStatus >) > ProvStatusCb;
/**
* RemoteEnrolleeResource constructor
* EnrolleeResource constructor
*
* @param enrolleeNWProvInfo Provisioning information for the Enrollee
*
* @throw ESBadRequestException is thrown if the parameters are invalid
*/
RemoteEnrolleeResource(const ProvConfig &enrolleeNWProvInfo,
const WiFiOnboadingConnection &onboardingconn);
EnrolleeResource(const WiFiOnboadingConnection &onboardingconn);
// EnrolleeResource(const ProvConfig &enrolleeNWProvInfo,
// const WiFiOnboadingConnection &onboardingconn);
~RemoteEnrolleeResource() = default;
~EnrolleeResource() = default;
/**
* Register provisioning status handler.
......@@ -73,11 +71,13 @@ namespace OIC
*
* @see ProvisioningStatus
*/
void registerProvStatusCallback (ProvStatusCb provStatusCb);
void registerInitRemoteEnrolleeStatusCallback (InitRemoteEnrolleeStatusCb callback);
void registerCapabilityStatusCallback (RequestCapabilityStatusCb callback);
void registerProvStatusCallback (DataProvStatusCb callback);
/**
* Construct Remote OIC resource using the enrollee host and connectivity information
* provided in the constructor of RemoteEnrolleeResource.
* provided in the constructor of EnrolleeResource.
*
* @throws InvalidParameterException If the provided information is invalid.
* @throws ESBadRequestException If resource is already constructed.
......@@ -86,6 +86,8 @@ namespace OIC
*/
ESResult constructResourceObject();
void getCapabilityData();
/**
* Function for provisioning of Remote Enrollee resource using the information provided.
*
......@@ -105,11 +107,16 @@ namespace OIC
private:
std::shared_ptr< OC::OCResource > m_ocResource;
std::mutex m_mutex;
ProvStatusCb m_provStatusCb;
InitRemoteEnrolleeStatusCb m_initRemoteEnrolleeStatusCb;
RequestCapabilityStatusCb m_requestCapabilityStatusCb;
DataProvStatusCb m_dataProvStatusCb;
ProvConfig m_ProvConfig;
WiFiOnboadingConnection m_wifiOnboardingconn;
bool m_discoveryResponse;
void getCapabilityResponse(const HeaderOptions& headerOptions, const OCRepresentation& rep,
const int eCode);
void getProvStatusResponse(const HeaderOptions& headerOptions, const OCRepresentation& rep,
const int eCode);
......
......@@ -32,7 +32,7 @@ namespace OIC
{
#define ENROLEE_SECURITY_TAG "ENROLEE_SECURITY"
class RemoteEnrolleeResource;
class EnrolleeResource;
class OCSecureResource;
/**
......@@ -43,14 +43,14 @@ namespace OIC
class EnrolleeSecurity
{
public:
EnrolleeSecurity(std::shared_ptr< RemoteEnrolleeResource > remoteEnrolleeResource,
EnrolleeSecurity(std::shared_ptr< EnrolleeResource > EnrolleeResource,
std::string secDbPath);
ESResult registerCallbackHandler(EnrolleeSecStatusCb enrolleeSecStatusCb,
SecurityPinCb securityPinCb, SecProvisioningDbPathCb secProvisioningDbPathCb);
EasySetupState performOwnershipTransfer();
private:
std::shared_ptr< RemoteEnrolleeResource > m_remoteEnrolleeResource;
std::shared_ptr< EnrolleeResource > m_EnrolleeResource;
EnrolleeSecStatusCb m_enrolleeSecStatusCb;
SecurityPinCb m_securityPinCb;
SecProvisioningDbPathCb m_secProvisioningDbPathCb;
......
......@@ -27,7 +27,7 @@ namespace OIC
{
namespace Service
{
class RemoteEnrolleeResource;
class EnrolleeResource;
class EnrolleeSecurity;
/**
......@@ -45,23 +45,10 @@ namespace OIC
*
* @throw ESBadRequestException is thrown if the parameters are invalid
*/
RemoteEnrollee(const ProvConfig& enrolleeNWProvInfo, const WiFiOnboadingConnection& connection) ;
RemoteEnrollee(const WiFiOnboadingConnection& wifiOnboardingconn);
~RemoteEnrollee() = default;
typedef std::shared_ptr< RemoteEnrollee > shared_ptr;
/**
* Callback definition to be invoked when EasySetup status is changed.
* The same callback will be invoked when there is an error in the
* EasySetup process.
*
* @see registerResourceHandler
* @see ResourceState
*/
typedef std::function< void(std::shared_ptr< EasySetupStatus >) >
EasySetupStatusCB;
#ifdef __WITH_DTLS__
/**
* Register Security status and other information callback handlers.
......@@ -80,18 +67,31 @@ namespace OIC
#endif //__WITH_DTLS__
/**
* Register EasySetup status handler.
* Start provisioning of target Enrollers information to the Enrollee.
*
* @param callback Callback to get EasySetup status.
* @param secProvisioningDbCB Callback to be invoked when the stack expects a
* path for the provisioning db.
* @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
*
* @throws InvalidParameterException If callback is an empty function or null.
* @throws ESBadRequestException If registration is already completed.
* @see RemoteEnrollee
*/
void initRemoteEnrollee(InitRemoteEnrolleeStatusCb callback);
/**
* Start provisioning of target Enrollers information to the Enrollee.
*
* @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
*
* @see RemoteEnrollee
*/
void startSecurityProvisioning(EnrolleeSecStatusCb callback);
/**
* Start provisioning of target Enrollers information to the Enrollee.
*
* @see EasySetupStatus
* @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.